Learnitweb

@WithMockUser Annotation in Spring Boot

1. Introduction

The @WithMockUser annotation is part of Spring Security’s testing framework. It allows you to simulate an authenticated user in a test method without actually going through the login process.

This is especially useful when writing unit or integration tests for secured endpoints or service methods protected by Spring Security.

2. Maven Dependency

Make sure you have this dependency in your pom.xml:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-test</artifactId>
    <scope>test</scope>
</dependency>

3. Basic Usage

@WithMockUser
@Test
void testWithDefaultUser() throws Exception {
    mockMvc.perform(get("/secured-endpoint"))
           .andExpect(status().isOk());
}

By default:

  • Username: user
  • Roles: ROLE_USER

4. Customize the Mock User

@WithMockUser(username = "admin", roles = {"ADMIN"})
@Test
void testWithAdminUser() throws Exception {
    mockMvc.perform(get("/admin"))
           .andExpect(status().isOk());
}

You can specify:

  • username
  • roles (Spring automatically prepends ROLE_ to each role)
  • password (not typically used in tests)
  • authorities (if you want to test with more fine-grained permissions)

5. Testing Secured Endpoints with MockMvc

Suppose you have a controller:

@RestController
@RequestMapping("/admin")
public class AdminController {

    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping
    public String getAdminPage() {
        return "Admin Page";
    }
}

Then in test:

@WebMvcTest(AdminController.class)
@AutoConfigureMockMvc
public class AdminControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @WithMockUser(username = "admin", roles = {"ADMIN"})
    @Test
    void adminAccessTest() throws Exception {
        mockMvc.perform(get("/admin"))
               .andExpect(status().isOk())
               .andExpect(content().string("Admin Page"));
    }

    @WithMockUser(username = "user", roles = {"USER"})
    @Test
    void forbiddenAccessTest() throws Exception {
        mockMvc.perform(get("/admin"))
               .andExpect(status().isForbidden());
    }
}

6. Limitations of @WithMockUser

  • It doesn’t invoke the real authentication mechanism.
  • It doesn’t load the actual user from the database.
  • It’s for testing security-related configuration, not authentication flow.