Spring Boot Testing: Unit, Integration & Performance

boot.cloud
Boot to Cloud
Published on May, 04 2026 3 min read 0 comments
image

In Week 6, we implemented professional error handling and logging.
Now, in Week 7, we’ll focus on testing your Spring Boot application β€” a critical skill for production-ready APIs.

We’ll cover:

  • Unit testing for isolated logic
  • Integration testing for controllers, services, and repositories
  • Performance testing basics
  • Using JUnit 5, Mockito, and Spring Test

Why Testing Matters

❌ Without tests:

  • Bugs sneak into production
  • Refactoring is risky
  • Deployment confidence is low

βœ… With tests:

  • You catch errors early
  • Code is maintainable and refactor-friendly
  • Continuous integration works reliably

Remember: Tests are documentation + safety net.

Step 1: Add Testing Dependencies

In pom.xml:

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

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>1.19.0</version>
    <scope>test</scope>
</dependency>
  • spring-boot-starter-test β†’ JUnit 5, AssertJ, Spring Test utilities
  • Mockito β†’ Mock dependencies in unit tests
  • TestContainers β†’ Integration testing with real databases

Step 2: Unit Testing Service Layer

Example: UserServiceTest

@ExtendWith(MockitoExtension.class)
public class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserService userService;

    @Test
    void testSaveUser() {
        User user = new User();
        user.setName("Mahabub");
        user.setEmail("[email protected]");

        when(userRepository.save(any(User.class))).thenReturn(user);

        User saved = userService.saveUser(user);

        assertNotNull(saved);
        assertEquals("Mahabub", saved.getName());
        verify(userRepository, times(1)).save(user);
    }
}

βœ… Key points:

  • Mock repository to isolate service logic
  • Verify interactions with verify()
  • Use assertEquals, assertNotNull, and assertThrows

Step 3: Integration Testing Controller Layer

Example: UserControllerTest

@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    @Test
    void testGetUserById() throws Exception {
        User user = new User();
        user.setId(1L);
        user.setName("Mahabub");

        when(userService.getUserById(1L)).thenReturn(Optional.of(user));

        mockMvc.perform(get("/api/users/1"))
               .andExpect(status().isOk())
               .andExpect(jsonPath("$.name").value("Mahabub"));
    }
}

βœ… Key points:

  • @SpringBootTest β†’ Loads full Spring context
  • @AutoConfigureMockMvc β†’ Mock HTTP requests
  • @MockBean β†’ Replace service with mock

Step 4: Integration Testing with Database

Use TestContainers to spin up a real database during tests:

@Testcontainers
@SpringBootTest
public class UserRepositoryTest {

    @Container
    public static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15")
        .withDatabaseName("testdb")
        .withUsername("user")
        .withPassword("pass");

    @Autowired
    private UserRepository userRepository;

    @Test
    void testSaveAndFindUser() {
        User user = new User();
        user.setName("Mahabub");
        user.setEmail("[email protected]");
        userRepository.save(user);

        Optional<User> found = userRepository.findById(user.getId());
        assertTrue(found.isPresent());
        assertEquals("Mahabub", found.get().getName());
    }
}

βœ… Benefits:

  • Tests run against real database
  • No need for manual setup/teardown
  • Supports CI/CD pipelines

Step 5: Testing Security (JWT Protected Endpoints)

@Test
void testProtectedEndpoint() throws Exception {
    mockMvc.perform(get("/api/admin")
            .header("Authorization", "Bearer " + jwtToken))
           .andExpect(status().isOk());
}
  • Generate JWT during test or mock authentication
  • Ensure role-based access works as expected

Step 6: Performance Testing Basics

For simple API performance checks:

  • Use Spring Boot Actuator / Metrics
  • Use JMeter / Gatling / k6 for load testing

Example using Actuator metrics:

management:
  endpoints:
    web:
      exposure:
        include: health, metrics, httptrace
  • Access /actuator/metrics/http.server.requests to see request times
  • Helps identify slow endpoints before production

Step 7: Best Practices for Testing

  1. Unit Tests: Isolate business logic
  2. Integration Tests: Test full flow with DB and controllers
  3. Use TestContainers for reproducible DB tests
  4. Mock external services to avoid network calls
  5. Test security and role-based access
  6. Measure performance for heavy endpoints

Tip: Aim for >80% coverage in critical modules

Week 7 Recap

βœ… Unit testing with Mockito
βœ… Controller & service integration tests
βœ… TestContainers for database
βœ… JWT-protected endpoint tests
βœ… Performance monitoring basics
βœ… Best practices for maintainable test suites

What’s Next? (Week 8)

πŸ‘‰ Spring Boot Production Deployment & Optimization

We’ll cover:

  • Profiles and environment variables
  • Packaging and Dockerization
  • Cloud deployment (AWS / Azure / GCP)
  • Performance tuning and monitoring

πŸ“Œ Action Items

βœ” Write unit tests for all services
βœ” Write integration tests for controllers
βœ” Test endpoints with JWT authentication
βœ” Add TestContainers for database
βœ” Measure response times with Actuator

0 Comments