Reputation: 1181
I have a Spring boot code with Aspectj. This code has written with basic MVC architecture. Then I just try to test it with MockMVC. But when I try to test it, Aspectj doesn't interrupted. Is there a special configuration about Aspectj?
Controller:
@GetMapping("user/{userId}/todo-list")
public ResponseEntity<?> getWaitingItems(@RequestUser CurrentUser currentUser){
...handle it with service method.
}
Aspect:
@Pointcut("execution(* *(.., @RequestUser (*), ..))")
void annotatedMethod()
{
}
@Before("annotatedMethod() && @annotation(requestUser)")
public void adviseAnnotatedMethods(JoinPoint joinPoint, RequestUser requestUser)
{
...
}
Test:
@WebMvcTest(value = {Controller.class, Aspect.class})
@ActiveProfiles("test")
@ContextConfiguration(classes = {Controller.class, Aspect.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class ControllerTest
{
@Autowired
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
private Controller controller;
@MockBean
private Service service;
@Before
public void setUp()
{
mockMvc = MockMvcBuilders
.webAppContextSetup(webApplicationContext)
.build();
}
@Test
public void getWaitingItems() throws Exception
{
mockMvc.perform(get("/user/{userId}/todo-list", 1L))
.andExpect(status().isOk());
}
}
Upvotes: 8
Views: 4879
Reputation: 171
There is no need for a @SpringBootTest
if you wanna do integration tests of specific controller (web layer) + your custom Aspect logic (AOP layer).
Try something like this
@WebMvcTest(controllers = {AnyController.class})
@Import({AopAutoConfiguration.class, ExceptionAspect.class})
public class ErrorControllerAdviceTest {
@Aspect
@Component
public class ExceptionAspect {}
Tested with Spring Boot 2.2.1.RELEASE and JUNIT5. I am unsure, if my solution is technically the same like @Deadpool answers
Upvotes: 15
Reputation: 40078
Spring @WebMvcTest will only instantiate web layer and it will not load complete application context
However, in this test, Spring Boot instantiates only the web layer rather than the whole context.
In order to test Aspectj you need to load whole application context using @SpringBootTest annotation
The @SpringBootTest annotation tells Spring Boot to look for a main configuration class (one with @SpringBootApplication, for instance) and use that to start a Spring application context
So annotate the test using @SpringBootTest
annotation
@SpringBootTest
@ActiveProfiles("test")
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
public class ControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
private Controller controller;
@Before
public void setUp() {
mockMvc = MockMvcBuilders
.webAppContextSetup(webApplicationContext)
.build();
}
@Test
public void getWaitingItems() throws Exception {
mockMvc.perform(get("/user/{userId}/todo-list", 1L))
.andExpect(status().isOk());
}
}
Upvotes: 3