Reputation: 2224
I have a simple controller that should only be accessible in a secured context.
In my application, I only whitelist other URLs, not /user
.
In the unit test for the single @GetResponse
I get an Http Status of 401 instead of a 200. I expect this, as it is secured.
When I actually run the application with a logged in user, I get a 200, and a valid result.
How can I Unit Test the behaviour of the request and any other secured controller paths?
Unit test:
@SpringBootTest
@AutoConfigureMockMvc
class UserControllerTest {
@InjectMocks
UserController userController;
@Autowired
private MockMvc mockMvc;
@Autowired
private ApplicationContext applicationContext;
@Test
void getUserNone() throws Exception {
mockMvc
.perform(MockMvcRequestBuilders.get("/user"))
.andExpect(status().isOk());
}
}
App:
@SpringBootApplication
public class WebApp extends WebSecurityConfigurerAdapter {
public static void main(final String... args) {
SpringApplication.run(WebApp.class, args);
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests(a -> a
.antMatchers("/error", "/css/**", "/webjars/**").permitAll()
.anyRequest().authenticated()
)
.exceptionHandling(e -> e
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
)
.oauth2Login();
}
}
Controller:
@Controller
public class UserController {
@GetMapping("/user")
public @ResponseBody
Map<String, Object> getUser(@AuthenticationPrincipal final OAuth2User principal) {
if (principal == null) {
return Collections.EMPTY_MAP;
} else {
return Collections.singletonMap("name", principal.getName());
}
}
}
Obviously, I could add /user
to the whitelisted paths, but that would be incorrect for any secured parts of the application.
Upvotes: 1
Views: 2307
Reputation: 1728
You can use the annotation @WithMockUser
and @WithAnonymousUser
which creates a fake Authentication
that is populated in SecurityContext
.
Documentation can be found here .
Example code:
@Test
@WithMockUser("john")
void testAuthorize() throws Exception {
mockMvc
.perform(MockMvcRequestBuilders.get("/user"))
.andExpect(status().isOk());
}
@Test
@WithAnonymousUser
void testUnauthorized() throws Exception {
mockMvc
.perform(MockMvcRequestBuilders.get("/user"))
.andExpect(status().isUnauthorized());
}
Upvotes: 3