I am trying to write a Unit tests for all of my service classes, but I cannot find a solution on how to mock a @PreAuthorize above my controller methods. As an example:
I have this function in controller:
@GetMapping("/users")
@PreAuthorize("hasAuthority('ADMIN')")
public ResponseEntity<List<User>> getUsers() {
return service.getUsers();
}
And this in my service class:
public ResponseEntity<List<User>> getUsers() {
return new ResponseEntity<>(userRepository.findAll(), HttpStatus.OK);
}
WebSecurity class:
protected void configure(HttpSecurity http) throws Exception {
http = http.cors().and().csrf().disable();
http = http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and();
http = http
.exceptionHandling()
.authenticationEntryPoint(
(request, response, ex) -> response.sendError(
HttpServletResponse.SC_UNAUTHORIZED,
ex.getMessage()
)
)
.and();
http.authorizeRequests()
.antMatchers(HttpMethod.GET, "/").permitAll()
.anyRequest().authenticated();
http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthenticationConverter());
}
public JwtAuthenticationConverter jwtAuthenticationConverter() {
JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
converter.setJwtGrantedAuthoritiesConverter(jwt ->
Optional.ofNullable(jwt.getClaimAsStringList("permissions"))
.stream()
.flatMap(Collection::stream)
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList())
);
return converter;
}
Now I am trying to write a unit test:
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTests {
@Autowired
private MockMvc mvc;
@MockBean
private UserService userService;
@Test
@WithMockJwtAuth(claims = @OpenIdClaims(otherClaims
= @Claims(stringClaims = @StringClaim(name = "permissions", value = "{ADMIN}"))))
public void getAllUsers_shouldBeSuccess() throws Exception {
ArrayList<User> users = new ArrayList<>();
users.add(new User("0", true, new Role("USER")));
when(userService.getUsers()).thenReturn(new ResponseEntity<>(users, HttpStatus.OK));
mvc.perform(get("/users"))
.andExpect(status().isOk());
}
}
But I receive an error on mvc.perform call:
java.lang.NoClassDefFoundError: `org/springframework/security/web/context/SecurityContextHolderFilter`
UPDATE:
I've tried https://github.com/ch4mpy/spring-addons and added @WithMockBearerTokenAuthentication, but I still receive the same error. Also to note: if I removed all @ and left only with @Test above the method, I receive 401 error.
@Test
@WithMockBearerTokenAuthentication(attributes = @OpenIdClaims(otherClaims
= @Claims(stringClaims = @StringClaim(name = "permissions", value = "{ADMIN}"))))
public void getAllUsers_shouldBeSuccess() throws Exception {
ArrayList<User> users = new ArrayList<>();
users.add(new User("0", true, new Role("USER")));
when(userService.getUsers()).thenReturn(new ResponseEntity<>(users, HttpStatus.OK));
mvc.perform(get("/users"))
.andExpect(status().isOk());
}