Модульное тестирование с 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>