Spring Boot
Authentication
Integration Tests
Java
Software Testing

Spring Boot Authentication for Integration Tests

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Authentication in Spring Boot integration tests can mean two different things: bypassing security so the rest of the stack can be tested, or exercising the real authentication flow end to end. The right approach depends on what the test is trying to prove, and mixing those goals usually leads to brittle or misleading tests.

Use @WithMockUser for Controller-Level Security Tests

If the goal is to verify authorization rules around controller endpoints, Spring Security’s test support is often enough.

java
1import org.junit.jupiter.api.Test;
2import org.springframework.beans.factory.annotation.Autowired;
3import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
4import org.springframework.boot.test.context.SpringBootTest;
5import org.springframework.security.test.context.support.WithMockUser;
6import org.springframework.test.web.servlet.MockMvc;
7
8import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
9import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
10
11@SpringBootTest
12@AutoConfigureMockMvc
13class AdminEndpointTest {
14
15    @Autowired
16    MockMvc mockMvc;
17
18    @Test
19    @WithMockUser(username = "alice", roles = {"ADMIN"})
20    void adminEndpointIsAccessibleToAdmin() throws Exception {
21        mockMvc.perform(get("/admin"))
22               .andExpect(status().isOk());
23    }
24}

This is fast and useful because it tests the web layer plus Spring Security rules without requiring a real login request.

Use Real Authentication for End-to-End Flows

If you need to verify the actual login mechanism, token issuance, or session behavior, use a full integration test that performs the real authentication request.

Example with a running server:

java
1import org.junit.jupiter.api.Test;
2import org.springframework.beans.factory.annotation.Autowired;
3import org.springframework.boot.test.context.SpringBootTest;
4import org.springframework.boot.test.web.client.TestRestTemplate;
5import org.springframework.boot.test.web.server.LocalServerPort;
6import org.springframework.http.*;
7
8import static org.assertj.core.api.Assertions.assertThat;
9
10@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
11class LoginFlowTest {
12
13    @LocalServerPort
14    int port;
15
16    @Autowired
17    TestRestTemplate restTemplate;
18
19    @Test
20    void loginEndpointReturnsSuccess() {
21        HttpHeaders headers = new HttpHeaders();
22        headers.setContentType(MediaType.APPLICATION_JSON);
23
24        String body = "{\"username\":\"alice\",\"password\":\"secret\"}";
25        HttpEntity<String> request = new HttpEntity<>(body, headers);
26
27        ResponseEntity<String> response =
28            restTemplate.postForEntity("http://localhost:" + port + "/login", request, String.class);
29
30        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
31    }
32}

This is slower, but it proves much more. It validates the real auth entrypoint instead of simulating an already-authenticated principal.

Decide Whether to Mock or Provision User Data

Authentication tests still need user state. You generally have two choices:

  • mock the security principal
  • provision test users in the backing store

For @WithMockUser, no real user row is required unless your application logic separately queries the user store. For end-to-end login tests, you usually need a known test user loaded through SQL, test configuration, or fixtures.

A profile-specific config can help:

properties
spring.profiles.active=test

Then the test profile can point to an in-memory database and preloaded users that are safe for automation.

Do Not Disable Security Unless the Test Intends To

A common anti-pattern is disabling security globally for integration tests and then claiming authentication was tested. That is only appropriate when the test is about unrelated business behavior and security would just be noise.

If you need an unsecured test profile for some suites, isolate it clearly so authentication-focused tests still run with real security.

A better split is:

  • security tests with Spring Security active
  • business-only integration tests using a separate test configuration when auth is irrelevant

That keeps the test intent honest.

Keep Test Scope Explicit

Authentication tests are easier to maintain when each test class has one purpose:

  • access-control test
  • login-flow test
  • token-expiry test
  • role-based authorization test

When one giant integration suite tries to cover every auth concern at once, failures become harder to diagnose and setup gets more fragile.

Common Pitfalls

  • Using @WithMockUser and assuming that proves the real login flow works tests the wrong thing.
  • Disabling security for all integration tests and then claiming authentication is covered leaves a major gap.
  • Forgetting to provision test users for real login tests makes failures look like security bugs when they are fixture problems.
  • Mixing business logic assertions and authentication setup in one huge test class makes maintenance harder.
  • Treating authentication and authorization as the same test concern misses important differences in what is actually being verified.

Summary

  • Use @WithMockUser for fast integration tests of secured controller behavior.
  • Use full HTTP login flows when the authentication mechanism itself must be tested.
  • Provision test users when real auth is part of the scenario.
  • Disable security only for tests that intentionally do not care about it.
  • Keep the test scope explicit so authentication coverage is meaningful and maintainable.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.