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.
Overview
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", "[email protected]");
when(userRepository.save(any(User.class))).thenReturn(newUser);
enrichmentService.registerNewUser("Alice", "[email protected]");
verify(userRepository).save(any(User.class));
verify(emailService).sendWelcomeEmail("[email protected]");
}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
Files 2 files
Install it by hand
Deska runs this for you, for every agent you pick. To run it yourself in a terminal:
npx skills add giuseppe-trisciuoglio/developer-kit --skill unit-test-service-layerMore from giuseppe-trisciuoglio
- shadcn-uigiuseppe-trisciuoglioProvides complete shadcn/ui component library patterns including installation, configuration, and implementation of accessible React components. Use when setting up shadcn/ui, installing components, building forms with React Hook Form and Zod, customizing themes with Tailwind CSS, or implementing UI patterns like buttons, dialogs, dropdowns, tables, and complex form layouts.22K installs on skills.sh0
- tailwind-css-patternsgiuseppe-trisciuoglioProvides comprehensive Tailwind CSS utility-first styling patterns including responsive design, layout utilities, flexbox, grid, spacing, typography, colors, and modern CSS best practices. Use when styling React/Vue/Svelte components, building responsive layouts, implementing design systems, or optimizing CSS workflow.17.3K installs on skills.sh0
- drizzle-orm-patternsgiuseppe-trisciuoglioProvides comprehensive Drizzle ORM patterns for schema definition, CRUD operations, relations, queries, transactions, and migrations. Proactively use for any Drizzle ORM development including defining database schemas, writing type-safe queries, implementing relations, managing transactions, and setting up migrations with Drizzle Kit. Supports PostgreSQL, MySQL, SQLite, MSSQL, and CockroachDB.5,000 installs on skills.sh0
- unit-test-bean-validationgiuseppe-trisciuoglioProvides patterns for unit testing Jakarta Bean Validation (JSR-380), including @Valid, @NotNull, @Min, @Max, @Email constraints with Hibernate Validator. Generates custom validator tests, constraint violation assertions, validation groups, and parameterized validation tests. Validates data integrity logic without Spring context. Use when writing validation tests, bean validation tests, or testing custom constraint validators.4,800 installs on skills.sh0
- nextjs-performancegiuseppe-trisciuoglioExpert Next.js performance optimization skill covering Core Web Vitals, image/font optimization, caching strategies, streaming, bundle optimization, and Server Components best practices. Use when optimizing Next.js applications for Core Web Vitals (LCP, INP, CLS), implementing next/image and next/font, configuring caching with unstable_cache and revalidateTag, converting Client Components to Server Components, implementing Suspense streaming, or analyzing and reducing bundle size. Supports Next.js 16 + React 19 patterns.4,700 installs on skills.sh0