This repository contains training materials for addressing two common issues in Spring Boot applications:
- Abuse of mocks in tests - Overuse of mocks can lead to brittle tests that are tightly coupled to implementation details.
- Reliance on HttpServletRequest and HttpServletResponse in service layers - Direct use of servlet API in service layers makes code harder to test and less reusable.
This repository is organized into branches that demonstrate the progression from problematic code to improved implementations:
- Examples of problematic code with excessive mocking
- Examples of service layer code tightly coupled to servlet API
- Tests that are brittle and hard to maintain
- Refactored code using "Testing Without Mocks" patterns
- Improved HTTP request handling with proper abstractions
- Tests that are more robust and less coupled to implementation details
Based on James Shore's "Testing Without Mocks: A Pattern Language", this approach focuses on:
- Using real objects instead of mocks when possible
- Creating "Nullables" or "Fakes" for infrastructure dependencies
- Using "Output Trackers" to verify behavior without mocks
- Structuring code to be more testable without mocks
- Abstracting HTTP request/response details behind interfaces
- Using DTOs to pass data between layers
- Keeping servlet API dependencies at the controller level only
This project uses:
- Java 21
- Spring Boot 3.2.0
- Gradle
To run the application:
./gradlew bootRun
To run the tests:
./gradlew test
- Identify issues with current approach
- Demonstrate how current tests break during refactoring
- Show how servlet API dependencies make testing difficult
- Introduce "Testing Without Mocks" patterns
- Refactor code to remove servlet API dependencies from service layer
- Create more robust tests using the new patterns
- Strategies for incrementally improving existing codebases
- Identifying good candidates for refactoring
- Measuring success: fewer test failures during refactoring