Модульное тестирование с AspectJ в Java

Я разрабатываю приложение, которое использует AspectJ с Java. В разработке я использую ajc и java вместе. AspectJ вызывает некоторые сегменты кода, когда это необходимо, и я хочу протестировать эти сегменты кода, вызываемые AspectJ. Я пытался сделать это с Mockito, но мне не удалось, кто-нибудь знает какой-либо другой способ проверить это?

2 ответа

Я только что создал JUnit4 Runner, чтобы разрешить AspectJ Load Time Weaving в тестовых примерах JUnit. Вот простой пример:

Я создал HelloService для возврата приветствия. И я создал Аспект, чтобы сделать имена в верхнем регистре приветствия. Наконец, я создал модульный тест, чтобы использовать HelloService с именем в нижнем регистре и ожидать результата в верхнем регистре.

Все детали примера являются частью проекта GitHub для справки: https://github.com/david-888/aspectj-junit-runner

Просто включите в свой путь к классу самый последний JAR аспекта aspectj-junit-runner. Тогда ваши тесты могут выглядеть так:

@AspectJConfig(classpathAdditions = "src/test/hello-resources")
@RunWith(AspectJUnit4Runner.class)
public class HelloTest {

    @Test
    public void getLiveGreeting() {
        String expected = "Hello FRIEND!";
        HelloService helloService = new HelloService();
        String greeting = helloService.sayHello("friend");
        Assert.assertEquals(expected, greeting);
    }

}

Я не уверен, как это сделать на простом Java и JUnit, но если у вас есть доступ к Spring-Integration-Test, вы можете легко подходить к MockMVC и поддерживать классы, которые он предлагает.

И ниже вы можете увидеть пример, в котором я тестирую контроллер, на котором установлен Aspect:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration
public class ControllerWithAspectTest {

    @Autowired
    private WebApplicationContext wac;
    @Autowired
    private MockMvc mockMvc;

    @Autowired
    @InjectMocks
    private MongoController mongoController;

    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
        // if you want to inject mocks into your controller
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testControllerWithAspect() throws Exception {
        MvcResult result = mockMvc
                .perform(
                        MockMvcRequestBuilders.get("/my/get/url")
                                .contentType(MediaType.APPLICATION_JSON)
                                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isOk()).andReturn();
    }

    @Configuration
    @EnableWebMvc
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    static class Config extends WebMvcConfigurerAdapter {

        @Bean
        public MongoAuditingAspect getAuditingAspect() {
            return new MongoAuditingAspect();
        }

    }

}

Вы можете использовать описанный выше подход, даже если у вас нет настроенного Spring в вашем приложении, так как подход, который я использовал, позволит вам иметь класс конфигурации (может и должен быть публичным классом, находящимся в его собственном файле).

И если @Configuration класс аннотируется @EnableAspectJAutoProxy(proxyTargetClass = true)Spring будет знать, что он должен включить аспекты в вашем тесте / приложении.

Если вам нужны какие-либо дополнительные разъяснения, я предоставлю их с дальнейшими изменениями.

РЕДАКТИРОВАТЬ:

Зависимость Maven Spring-Test:

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring.version}</version>
        <scope>test</scope>
</dependency>
Другие вопросы по тегам