I am trying to learn more about testing in a spring boot project.
The following example shows a very simple test that checks the response of a service or endpoint.
@WebMvcTest(MyController.class)
public class MyControllerTests {
@Autowired
private MockMvc mockMvc;
@MockBean
private MyService service;
@Test
public void getPing() throws Exception {
when(service.ping()).thenReturn("pong");
this.mockMvc.perform(get("/ping")).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("pong")));
}
}
As soon as an individualized security config with custom components is used the test fails with NoSuchBeanDefinitionException.
For example: Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'my.project.component.MyLogoutSuccessHandler' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
The security configuration looks like this:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Configuration
@Order(1)
public static class FooConfigurationAdapter extends WebSecurityConfigurerAdapter {
private final MyLogoutSuccessHandler myLogoutSuccessHandler;
private final MyAuthenticationEntryPoint myAuthenticationEntryPoint;
@Autowired
FooConfigurationAdapter(MyLogoutSuccessHandler myLogoutSuccessHandler,
MyAuthenticationEntryPoint myAuthenticationEntryPoint) {
this.myLogoutSuccessHandler = myLogoutSuccessHandler;
this.myAuthenticationEntryPoint = myAuthenticationEntryPoint;
}
protected void configure(HttpSecurity http) throws Exception {
// ...
}
}
@Configuration
@Order(2)
public static class BarConfigurationAdapter extends WebSecurityConfigurerAdapter {
private final MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
private final UserDetailsService userDetailsService;
@Autowired
BarConfigurationAdapter(MyAuthenticationSuccessHandler myAuthenticationSuccessHandler,
UserDetailsService userDetailsService) {
this.myAuthenticationSuccessHandler = myAuthenticationSuccessHandler;
this.userDetailsService = userDetailsService;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// ...
}
}
}
MyLogoutSuccessHandler looks like the following in this example:
@Component
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
// ...
}
}
Can someone please explain to me how the test must look like to work with the autowired components?