Developer-kit unit-test-service-layer
Provides patterns for unit testing service layer with Mockito. Creates isolated tests that mock repository calls, verify method invocations, test exception scenarios, and stub external API responses. Use when testing service behaviors and business logic without database or external services.
install
source · Clone the upstream repo
git clone https://github.com/giuseppe-trisciuoglio/developer-kit
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/giuseppe-trisciuoglio/developer-kit "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/developer-kit-java/skills/unit-test-service-layer" ~/.claude/skills/giuseppe-trisciuoglio-developer-kit-unit-test-service-layer && rm -rf "$T"
manifest:
plugins/developer-kit-java/skills/unit-test-service-layer/SKILL.mdsource content
Unit Testing Service Layer with Mockito
Overview
Provides patterns for unit testing
@Service classes using Mockito. Mocks repository calls, verifies method invocations, tests exception scenarios, and stubs external API responses. Enables fast, isolated tests without Spring container or database.
When to Use
- Testing business logic in
classes@Service - Mocking repository and external client dependencies
- Verifying service interactions with mocked collaborators
- Testing error handling and edge cases in services
- Writing fast, isolated unit tests (no database, no API calls)
Instructions
Follow this workflow to test service layer with Mockito, including validation checkpoints:
1. Setup Test Class
Use
@ExtendWith(MockitoExtension.class) to enable Mockito annotations.
2. Declare Mocks with @Mock
and @InjectMocks
@Mock@InjectMocksUse
@Mock for dependencies (repositories, clients) and @InjectMocks for the service under test.
3. Arrange-Act-Assert with Validation
Arrange: Create test data and configure mock return values using
when().thenReturn().
Act: Execute the service method being tested.
Assert:
- Verify returned values with AssertJ assertions
- Verify mock interactions with
verify() - Validation checkpoint: Run test and confirm green bar
4. Test Exception Scenarios
Configure mocks to throw exceptions with
when().thenThrow().
Validation checkpoint: Verify exception type and message
5. Verify Complete Coverage
- Run full test suite:
ormvn testgradle test - Check coverage report:
mvn test jacoco:report - Validation checkpoint: Confirm all service methods have corresponding tests
Examples
Basic Service Test Pattern
@ExtendWith(MockitoExtension.class) class UserServiceTest { @Mock private UserRepository userRepository; @InjectMocks private UserService userService; @Test void shouldReturnUserWhenFound() { // Arrange User expected = new User(1L, "Alice"); when(userRepository.findById(1L)).thenReturn(Optional.of(expected)); // Act User result = userService.getUser(1L); // Assert assertThat(result.getName()).isEqualTo("Alice"); verify(userRepository).findById(1L); } @Test void shouldThrowWhenUserNotFound() { // Arrange when(userRepository.findById(999L)).thenReturn(Optional.empty()); // Act & Assert assertThatThrownBy(() -> userService.getUser(999L)) .isInstanceOf(UserNotFoundException.class); } }
Verify Method Invocations
@Test void shouldSendEmailOnUserCreation() { User newUser = new User(1L, "Alice", "alice@example.com"); when(userRepository.save(any(User.class))).thenReturn(newUser); enrichmentService.registerNewUser("Alice", "alice@example.com"); verify(userRepository).save(any(User.class)); verify(emailService).sendWelcomeEmail("alice@example.com"); }
For additional patterns (multiple dependencies, argument captors, async services, InOrder verification), see
references/examples.md.
Best Practices
- Use
for JUnit 5 integration@ExtendWith(MockitoExtension.class) - Mock only direct dependencies of the service under test
- Verify interactions to ensure correct collaboration
- Test one behavior per test method - keep tests focused
- Use descriptive variable names:
,expectedUser
,actualUsercaptor - Create real instances for value objects and DTOs (don't mock them)
Constraints and Warnings
- Do not mock value objects or DTOs; create real instances with test data.
- Avoid mocking too many dependencies; consider refactoring if a service has too many collaborators.
- Tests must be independent; do not rely on execution order.
- Be cautious with
; partial mocking is harder to understand and maintain.@Spy - Do not test private methods directly; test them through public method behavior.
- Argument matchers (
,any()
) cannot be mixed with actual values in the same stub.eq() - Avoid over-verifying; verify only interactions important to the test scenario.