-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Our current test suite heavily use integration tests using @SpringBootTest, which makes tests slow, brittle, and harder to maintain. We need to refactor the entire test suite to prioritize pure unit tests (95%) over integration tests (5%) and ensure we only test the code that actually exists in our application.
-
Maximize unit test coverage - Replace most @SpringBootTest tests with lightweight @ExtendWith(MockitoExtension.class) tests
Test only production code - No testing of Spring framework, third-party libraries, or non-existent behaviors
Improve test speed - Unit tests should execute in < 100ms each
Increase maintainability - Clear, focused tests that are easy to understand and modify -
Unit Tests First (95% of all tests)
Characteristics of a proper unit test:
Tests ONE class in isolation
Uses @ExtendWith(MockitoExtension.class) (NOT @SpringBootTest)
Mocks ALL dependencies with @mock and @Injectmocks
No database, no Spring context, no MockMvc
Executes in < 100ms
Example structure:
@ExtendWith(MockitoExtension.class)
class ServiceNameUnitTest {
@Mock
private DependencyService dependencyService;
@Mock
private Repository repository;
@InjectMocks
private ServiceName serviceUnderTest;
@Test
void shouldReturnExpectedResultWhenValidInput() {
// Arrange
InputData input = new InputData("value");
when(dependencyService.process(any())).thenReturn(expectedData);
// Act
Result result = serviceUnderTest.methodToTest(input);
// Assert
assertThat(result).isNotNull()
.extracting("field")
.isEqualTo(expectedValue);
verify(dependencyService).process(any());
}
}-
Integration Tests (5% maximum)
Only use when:
Testing critical cross-component interactions
Testing custom repository queries
End-to-end controller testing (use @WebMvcTest when possible, not @SpringBootTest) -
Test Only What Exists
To do:
Analyze the production class before writing tests
Test each public method
Cover conditional branches (if/else, switch)
Test error cases (exceptions, validations)
Test edge cases and boundary conditions
Not to do:
Test unimplemented behaviors
Test methods from other microservices/libraries
Test Spring infrastructure (dependency injection, transactions)
Test frameworks (JPA, Jackson, Spring MVC)
Test multiple classes together in unit tests
Test private methods directly