unit-test-service-layer
giuseppe-trisciuoglio/developer-kit
Unit test service layer with Mockito: mock dependencies, verify interactions, test business logic in isolation.
What is unit-test-service-layer?
Provides patterns for unit testing @Service classes using Mockito to mock repositories and external dependencies. Creates fast, isolated tests without database or Spring container. Use when testing service business logic, error handling, and method interactions.
- Mock repository and external client dependencies with @Mock and @InjectMocks
- Verify service method invocations and interactions with mocked collaborators
- Test exception scenarios and error handling with when().thenThrow()
- Stub external API responses and configure mock return values
- Run isolated unit tests without database or API calls
- Check test coverage with Maven/Gradle coverage reports
How to install unit-test-service-layer
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill unit-test-service-layer- JUnit 5 (with @ExtendWith support)
- Mockito library in project dependencies
- Maven or Gradle for running tests and coverage reports
How to use unit-test-service-layer
- 1.Create a test class with @ExtendWith(MockitoExtension.class)
- 2.Declare mock dependencies with @Mock and the service under test with @InjectMocks
- 3.Write Arrange-Act-Assert tests: configure mocks with when().thenReturn(), execute service method, assert results
- 4.Use verify() to confirm mock interactions occurred as expected
- 5.Test exception paths with when().thenThrow() and assertThatThrownBy()
- 6.Run mvn test or gradle test to validate all tests pass
- 7.Generate coverage report with mvn test jacoco:report to confirm service method coverage
Use cases
- Testing business logic in @Service classes without database access
- Mocking repository calls to verify service behavior in isolation
- Testing error handling and exception scenarios in services
- Verifying that services correctly invoke external clients and APIs
- Writing fast unit tests for service layer as part of CI/CD pipeline
- Backend developers writing Java/Spring services
- QA engineers building unit test suites
- Teams practicing test-driven development
- Developers optimizing test execution speed
unit-test-service-layer FAQ
No. Create real instances of value objects and DTOs with test data. Only mock direct dependencies like repositories and external clients.
Use verify(mockDependency).methodName() after the Act phase to confirm the interaction occurred with expected arguments.
This signals a design issue. Consider refactoring the service to have fewer collaborators or extracting logic into smaller, focused services.
No. Argument matchers (any(), eq()) cannot be mixed with actual values in the same when().thenReturn() call. Use all matchers or all actual values.
No. Test private methods indirectly through public method behavior. If a private method is complex enough to need direct testing, consider extracting it to a separate class.
Full instructions (SKILL.md)
Source of truth, from giuseppe-trisciuoglio/developer-kit.
name: unit-test-service-layer description: 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. allowed-tools: Read, Write, Bash, Glob, Grep
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
@Serviceclasses - 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
Use @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:
mvn testorgradle 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
@ExtendWith(MockitoExtension.class)for JUnit 5 integration - 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,actualUser,captor - 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
@Spy; partial mocking is harder to understand and maintain. - Do not test private methods directly; test them through public method behavior.
- Argument matchers (
any(),eq()) cannot be mixed with actual values in the same stub. - Avoid over-verifying; verify only interactions important to the test scenario.
References
Related skills
More from giuseppe-trisciuoglio/developer-kit and the wider catalog.

unit-test-utility-methods
Test patterns for utility classes, static methods, and pure functions with edge case coverage.

unit-test-wiremock-rest-api
Unit test REST API integrations with WireMock stubs, request verification, and error simulation.

wiremock-standalone-docker
Provides patterns and configurations for running WireMock as a standalone Docker container. Generates mock HTTP endpoints, creates stub mappings for testing, validates integration scenarios, and simulates error conditions. Use when you need to mock APIs, create a mock server, stub external services, simulate third-party APIs, or fake API responses for integration testing.

zod-validation-utilities
Creates reusable Zod v4 schemas, validates API payloads, forms, and configuration input, transforms and coerces data safely, and handles validation errors with strong type inference for TypeScript applications. Use when designing validation layers, parsing `z.string()`, `z.object()`, or `z.email()` schemas, or implementing runtime type-safe data validation.

gluestack-ui-v4:components
Component usage patterns for gluestack-ui v4 - covers component selection, props vs className, compound patterns, icons, and provider setup.

gmgn-cooking
Create and launch meme coins on Solana, BSC, and Base launchpads via bonding curve fair launch.