mhrsalehi
mhrsalehi

Reputation: 1394

How to test Controllers with @WebMvcTest when using spring security?

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

Answers (2)

vi0
vi0

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

vijay elango
vijay elango

Reputation: 11

We can use the @WithMockUser.

reference:

https://www.baeldung.com/spring-security-integration-tests

Upvotes: 0

Related Questions