Mastering Unit Testing in Spring Boot: How I Achieved 70%+ Coverage for Open Source
Source: Dev.to
⚠️ Collection Error: Content refinement error: Error: 429 “you (bkperio) have reached your session usage limit, upgrade for higher limits: https://ollama.com/upgrade (ref: 40bf9abb-b133-4910-9ddc-e5f105cbb440)”
Testing is not about finding bugs; it’s about gaining the confidence to ship code.
The Challenge The DecisionService I was testing relied on multiple repositories and complex DTO mapping. When I first ran my tests, I kept hitting a wall: java.lang.NullPointerException: Cannot invoke “OffsetDateTime.toInstant()” because … is null This happened because the service was converting entity timestamps to Instants for the API response, but in a Mockito environment, these fields aren’t automatically populated like they are in a real database. The Technical Solution To fix this, I had to ensure that every Mock object was fully initialized with the fields required by the Mapper. Here’s a snippet of the successful test setup:
@Test @DisplayName(“Should create decision successfully”) void createDecision_Success() { // 1. Prepare the Request CreateDecisionRequest request = new CreateDecisionRequest( “Feature”, “Body”, “repo-1”, DecisionStatus.PROPOSED, List.of(“java”) );
// 2. Build the Mock Entity with required fields (Crucial Step!)
Decision savedDecision = Decision.builder()
.id("dec-1")
.author(mockUser)
.repo(mockRepo)
.createdAt(OffsetDateTime.now()) // The fix for NPE!
.status(DecisionStatus.PROPOSED)
.build();
// 3. Mock the behavior
when(decisionRepository.save(any(Decision.class))).thenReturn(savedDecision);
// 4. Act & Assert
DecisionResponse response = decisionService.createDecision(request, currentUserId);
assertThat(response.title()).isEqualTo("Feature");
}
Key Takeaways Mocks are not Magic: If your service maps an entity to a DTO, your Mock entity must have all the fields the Mapper touches. Context Matters: In Spring Boot tests, pay attention to OffsetDateTime and relational objects like Repo or User. Clean over Complex: Using thenReturn() is often more readable and predictable than thenAnswer() for simple Unit Tests. Call to Action Writing these tests increased the project’s reliability and helped me understand the inner workings of Spring Boot even better. Are you working on GSSoC 2026? Let’s connect! GitHub: MohammedGhallab.
java #springboot #testing #opensource