MockMvc with Spring Security: End-to-End and Method Security Testing
Fast recall
Quick revision
Core answer
@SpringBootTest + @AutoConfigureMockMvc) so the `SecurityFilterChain` is wired into the MockMvc instance via `SecurityMockMvcConfigurers.springSecurity()` (auto-applied with @WebMvcTest). Use `with(csrf())` for state-changing requests in CSRF-enabled chains. Method-level security (@PreAuthorize/@PostAuthorize) needs @SpringBootTest because it depends on AOP proxies that @WebMvcTest does not create — use @EnableMethodSecurity and assert AccessDeniedException. For each rule, write a positive test (allowed role -> 2xx) and a negative test (wrong role -> 403, no auth -> 401). Verify the security context with `SecurityMockMvcResultMatchers.authenticated()` and .withAuthorities(...).Whether the candidate can structure a real security test suite that catches regressions, not a happy-path smoke test.
Testing controllers with @WebMvcTest while expecting @PreAuthorize annotations on services to fire — they do not, because the proxy isn't created.
Discuss negative tests as first-class citizens, custom @WithSecurityContext factories for JWT, integration tests with Testcontainers Keycloak, and the @WebMvcTest vs @SpringBootTest decision matrix.
Interview-ready guide
Interview answer
MockMvc setup
@WebMvcTest(Controller.class)+@Import(SecurityConfig.class)- MockMvc auto-configured with security filter chain via
SecurityMockMvcConfigurers.springSecurity() @MockBeanfor service dependencies
Method security
@SpringBootTest(not@WebMvcTest) so AOP proxies are created@EnableMethodSecurityin test config@WithMockUser+assertThrows(AccessDeniedException.class, ...)
CSRF
with(csrf())for state-changing requests- Write one explicit test that omits it to verify CSRF protection is active
JWT Resource Server
- Use
with(jwt().jwt(jb -> jb.subject().claim(...)).authorities(...))per request - Or build
@WithMockJwtUserwithWithSecurityContextFactoryfor reuse
Negative tests are first-class
- For every
requestMatchersrule and every@PreAuthorize:- Allowed role -> 2xx
- Wrong role -> 403
- No auth -> 401
- Missing CSRF -> 403 (one canary test)
Result matchers beyond status
SecurityMockMvcResultMatchers.authenticated().withAuthorities(...)- Distinguishes 200 from
permitAll()vs 200 from authenticated access
End-to-end
- Testcontainers Keycloak for real OAuth2 flows
- Real JWKS, signature,
iss/audvalidation - Sparingly for critical flows; not every endpoint
Common mistakes
@WebMvcTestfor method security -> silent false positive- Missing
@EnableMethodSecurity-> annotations ignored - Missing
with(csrf())-> misdiagnosed 403 @WithMockUserfor JWT endpoints -> wrong token type
MockMvc with Spring Security: End-to-End and Method Security Testing
Direct Answer
End-to-end MockMvc security tests require @WebMvcTest (or @SpringBootTest + @AutoConfigureMockMvc) so the SecurityFilterChain is wired into the MockMvc instance via SecurityMockMvcConfigurers.springSecurity() (auto-applied with @WebMvcTest). Use with(csrf()) for state-changing requests in CSRF-enabled chains. Method-level security (@PreAuthorize/@PostAuthorize) needs @SpringBootTest because it depends on AOP proxies that @WebMvcTest does not create — use @EnableMethodSecurity and assert AccessDeniedException. For each rule, write a positive test (allowed role -> 2xx) and a negative test (wrong role -> 403, no auth -> 401). Verify the security context with SecurityMockMvcResultMatchers.authenticated() and .withAuthorities(...).
Common Mistakes & Pitfalls
Testing controllers with @WebMvcTest while expecting @PreAuthorize annotations on services to fire — they do not, because the proxy isn't created.
Check your understanding
Answer these without looking back at the article.
- Why does @WebMvcTest fail to test @PreAuthorize on services?
- How do you test a controller that uses both session-based form login and JWT API auth?
- How do you assert that a request was authenticated with a specific authority, not just that it returned 200?
- When is Testcontainers Keycloak the right tool over MockMvc?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.