All posts

Testing Error Scenarios in Spring Boot Applications

Comprehensive guide to testing error scenarios in Spring Boot with MockMvc, exception handlers, integration tests, and fault injection.

Testing Error Scenarios in Spring Boot Applications

Spring Boot's test framework makes it straightforward to verify error handling. Here's how to cover failure scenarios thoroughly.

MockMvc Error Tests

@WebMvcTest(OrderController.class)
class OrderControllerErrorTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private OrderService orderService;

    @Test
    void getOrder_notFound_returns404() throws Exception {
        when(orderService.findById("123"))
            .thenThrow(new ResourceNotFoundException("Order", "123"));

        mockMvc.perform(get("/api/orders/123"))
            .andExpect(status().isNotFound())
            .andExpect(jsonPath("$.errorCode").value("RESOURCE_NOT_FOUND"))
            .andExpect(jsonPath("$.message").value("Order with id 123 not found"));
    }

    @Test
    void createOrder_invalidBody_returns400() throws Exception {
        mockMvc.perform(post("/api/orders")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"quantity\": -1}"))
            .andExpect(status().isBadRequest())
            .andExpect(jsonPath("$.errors").isArray());
    }

    @Test
    void createOrder_serviceTimeout_returns503() throws Exception {
        when(orderService.create(any()))
            .thenThrow(new ServiceUnavailableException("Payment service timeout"));

        mockMvc.perform(post("/api/orders")
                .contentType(MediaType.APPLICATION_JSON)
                .content(validOrderJson))
            .andExpect(status().isServiceUnavailable());
    }
}

Integration Test Error Scenarios

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class OrderIntegrationTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void createOrder_duplicateOrder_returns409() {
        // Create first order
        restTemplate.postForEntity("/api/orders", orderRequest, Order.class);

        // Attempt duplicate
        ResponseEntity<ErrorResponse> response = restTemplate.postForEntity(
            "/api/orders", orderRequest, ErrorResponse.class
        );

        assertEquals(HttpStatus.CONFLICT, response.getStatusCode());
    }
}

Test Exception Handler

@Test
void globalHandler_handlesUnexpectedExceptions() throws Exception {
    when(orderService.findById(any()))
        .thenThrow(new RuntimeException("Unexpected"));

    mockMvc.perform(get("/api/orders/123"))
        .andExpect(status().isInternalServerError())
        .andExpect(jsonPath("$.message").value("An unexpected error occurred"));
}

Key Scenarios to Cover

  • Validation errors — missing fields, invalid formats, constraint violations
  • Authentication failures — expired JWT, missing credentials
  • Database constraints — unique violations, foreign key constraints
  • External service failures — timeouts, connection refused, 5xx responses
  • Concurrency conflicts — optimistic locking exceptions

Use Bugsly in your staging and production environments to discover error scenarios your tests don't cover. Each new production error becomes a candidate for a new test case.

Try Bugsly Free

AI-powered error tracking that explains your bugs. Set up in 2 minutes, free forever for small projects.

Get Started Free