Reputation: 1394
I want to use @WebMvcTest
to test the web layer of a spring boot (version 2.7) application secured by spring security. as you may know @WebMvcTest
only configure Web infrastructure, from @WebMvcTest
doc:
Annotation that can be used for a Spring MVC test that focuses only on Spring MVC components. Using this annotation will disable full auto-configuration and instead apply only configuration relevant to MVC tests (i.e. @Controller, @ControllerAdvice, @JsonComponent, Converter/GenericConverter, Filter, WebMvcConfigurer and HandlerMethodArgumentResolver beans but not @Component, @Service or @Repository beans).
the problem is that because the security config depends on some beans, TokenAuthenticationProvider
and UsernamePasswordAuthenticationProvider
(and these beans themselves depend on other beans such as UserService
, TokenService
and others. these beans are configured by @Component
and @Bean
). so my test fails because spring can not find WebSecurityConfig
's dependencies.
what is the proper way to test controllers (using @WebMvcTest
) in this case?
should I mock all these dependencies? (this does not seem right because these beans are fairly complex)
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final TokenAuthenticationProvider tokenProvider;
private final UsernamePasswordAuthenticationProvider usernamePasswordAuthenticationProvider;
public WebSecurityConfig(TokenAuthenticationProvider tokenProvider, UsernamePasswordAuthenticationProvider usernamePasswordAuthenticationProvider) {
this.tokenProvider = tokenProvider;
this.usernamePasswordAuthenticationProvider = usernamePasswordAuthenticationProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(tokenProvider)
.authenticationProvider(usernamePasswordAuthenticationProvider);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
.
.
.
.and()
.addFilterBefore(new TokenAuthenticationFilter2(authenticationManagerBean()), BasicAuthenticationFilter.class)
.addFilterBefore(new UsernamePasswordAuthenticationFilter(authenticationManagerBean()), BasicAuthenticationFilter.class);
}
}
Upvotes: 5
Views: 3427
Reputation: 350
Spring Boot 2.7.5
If you do not add @AutoConfigureMockMvc(addFilters = false) then tests will return 401, 403
@RequiredArgsConstructor
@EnableWebSecurity
@Profile("!test")
public class SecurityConfig extends WebSecurityConfigurerAdapter
{...}
@WebMvcTest(value = MyController.class)
@ActiveProfiles("test")
@AutoConfigureMockMvc(addFilters = false)
class MyControllerTest {
{...}
Upvotes: 4
Reputation: 11
We can use the @WithMockUser.
reference:
https://www.baeldung.com/spring-security-integration-tests
Upvotes: 0