I have the following Test class:
My PokemonControllerTest:
@AutoConfigureMockMvc(addFilters = true)
@ExtendWith(SpringExtension.class)
@WebMvcTest(PokemonController.class)
public class PokemonControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private PokemonService pokemonService;
@Autowired
private ObjectMapper objectMapper;
private Pokemon pokemon;
private PokemonDTO pokemonDTO;
@BeforeEach
public void init(){
pokemon = Pokemon.builder().name("pokemon1").type("idk").build();
pokemonDTO = PokemonDTO.builder().name("pokemonDto1").type("idk2").build();
}
@Test
@WithMockUser(value = "spring", roles = {"USER", "ADMIN"})
public void PokemonController_CreatePokemon_ReturnCreated() throws Exception{
// when(pokemonService.createPokemon(ArgumentMatchers.any())).willAnswer((invocation->invocation.getArgument(0)));
when(pokemonService.createPokemon(ArgumentMatchers.any())).thenAnswer((invocation->invocation.getArgument(0)));
ResultActions response = mockMvc.perform(MockMvcRequestBuilders.post("/api/pokemons").contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsString(pokemonDTO)));
response.andExpect(MockMvcResultMatchers.status().isCreated())
.andExpect(MockMvcResultMatchers.jsonPath("$.name", CoreMatchers.is(pokemonDTO.getName())))
.andExpect(MockMvcResultMatchers.jsonPath("$.type", CoreMatchers.is(pokemonDTO.getType())));
}
@Test
@WithMockUser(value = "spring", roles = {"USER", "ADMIN"})
public void PokemonController_GetPokemonById_ReturnPokemon()throws Exception{
when(pokemonService.getPokemonById(ArgumentMatchers.anyInt())).thenReturn(pokemonDTO);
mockMvc.perform(MockMvcRequestBuilders.get("/api/pokemons/{id}", "1").accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isOk());
}
}
and the following configuration to secure API and allow only to the user configured:
WebSecurityConfigurer
@Configuration
public class WebSecurityConfigurer {
@Bean
public InMemoryUserDetailsManager userDetailsService(PasswordEncoder passwordEncoder) {
UserDetails user = User.withUsername("spring")
.password(passwordEncoder.encode("secret"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(request -> request.requestMatchers(new AntPathRequestMatcher("/api/**"))
.hasRole("USER"))
.authorizeHttpRequests(request -> request.requestMatchers(new AntPathRequestMatcher("/public/**"))
.permitAll())
.httpBasic(Customizer.withDefaults())
.build();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
I am expecting the test to pass but it doesn’t. the exact message is:
PokemonControllerTest.PokemonController_CreatePokemon_ReturnCreated:68 Status expected:<201> but was:<403>
With 403 being forbidden meaning my configuration does not work because I am sending the following: @WithMockUser(value = "spring", roles = {"USER", "ADMIN"})
from the test class you can see.