
Unit Test Service Layer
Generate Mockito and JUnit 5 unit tests for Java @Service classes with mocked repositories and AssertJ assertions.
Overview
Unit Test Service Layer is an agent skill for the Ship phase that teaches Mockito and JUnit 5 patterns for unit testing Java @Service classes with mocked dependencies.
Install
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill unit-test-service-layerWhat is this skill?
- Maven and Gradle test dependency snippets for JUnit Jupiter, Mockito, and AssertJ
- @ExtendWith(MockitoExtension) pattern with @Mock and @InjectMocks for services
- Examples for single and multiple mocked dependencies on repository calls
- AssertJ-style assertions paired with Mockito verify and stubbing
- Copy-paste-ready Java test class structure for UserService-style CRUD flows
Adoption & trust: 1.2k installs on skills.sh; 271 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You have @Service business logic but no consistent Mockito setup or examples for mocking repositories in isolated unit tests.
Who is it for?
Solo builders maintaining Java Spring-style services who want fast, Mockito-based unit tests before merge or deploy.
Skip if: Teams needing full Spring Boot @WebMvcTest integration tests, Testcontainers, or non-Java stacks.
When should I use this skill?
Adding or fixing unit tests for Java @Service classes that depend on repositories or other injectable collaborators.
What do I get? / Deliverables
Your agent produces JUnit 5 test classes with @Mock/@InjectMocks, AssertJ assertions, and verify/stub patterns ready to run in Maven or Gradle test scopes.
- JUnit 5 test class with MockitoExtension
- Mocked dependency wiring and assertion examples
Recommended Skills
Journey fit
Service-layer unit tests are written during the ship phase before release, when you lock behavior behind fast, isolated tests. Canonical shelf is testing because the skill is entirely focused on Mockito patterns, dependency mocking, and JUnit 5 examples—not production service code.
How it compares
Focused Mockito service-unit templates—not a full test pyramid or CI runner skill.
Common Questions / FAQ
Who is unit-test-service-layer for?
Java backend solo builders and small teams testing @Service classes with Mockito, JUnit 5, and AssertJ on Maven or Gradle projects.
When should I use unit-test-service-layer?
During Ship when adding or refactoring service methods, before release when you need isolated tests without a database, or when onboarding an agent to your existing repository-mock conventions.
Is unit-test-service-layer safe to install?
It is documentation and code examples only; review the Security Audits panel on this Prism page and inspect the parent developer-kit repo before trusting generated test code in CI.
SKILL.md
READMESKILL.md - Unit Test Service Layer
# Unit Testing Service Layer - Examples Complete code examples for unit testing `@Service` classes with Mockito. ## Setup with Mockito and JUnit 5 ### Maven ```xml <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <scope>test</scope> </dependency> ``` ### Gradle ```kotlin dependencies { testImplementation("org.junit.jupiter:junit-jupiter") testImplementation("org.mockito:mockito-core") testImplementation("org.mockito:mockito-junit-jupiter") testImplementation("org.assertj:assertj-core") } ``` ## Basic Pattern: Service with Mocked Dependencies ### Single Dependency ```java import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import static org.mockito.Mockito.*; import static org.assertj.core.api.Assertions.*; @ExtendWith(MockitoExtension.class) class UserServiceTest { @Mock private UserRepository userRepository; @InjectMocks private UserService userService; @Test void shouldReturnAllUsers() { // Arrange List<User> expectedUsers = List.of( new User(1L, "Alice"), new User(2L, "Bob") ); when(userRepository.findAll()).thenReturn(expectedUsers); // Act List<User> result = userService.getAllUsers(); // Assert assertThat(result).hasSize(2); assertThat(result).containsExactly( new User(1L, "Alice"), new User(2L, "Bob") ); verify(userRepository, times(1)).findAll(); } } ``` ### Multiple Dependencies ```java @ExtendWith(MockitoExtension.class) class UserEnrichmentServiceTest { @Mock private UserRepository userRepository; @Mock private EmailService emailService; @Mock private AnalyticsClient analyticsClient; @InjectMocks private UserEnrichmentService enrichmentService; @Test void shouldCreateUserAndSendWelcomeEmail() { User newUser = new User(1L, "Alice", "alice@example.com"); when(userRepository.save(any(User.class))).thenReturn(newUser); doNothing().when(emailService).sendWelcomeEmail(newUser.getEmail()); User result = enrichmentService.registerNewUser("Alice", "alice@example.com"); assertThat(result.getId()).isEqualTo(1L); assertThat(result.getName()).isEqualTo("Alice"); verify(userRepository).save(any(User.class)); verify(emailService).sendWelcomeEmail("alice@example.com"); verify(analyticsClient, never()).trackUserRegistration(any()); } } ``` ## Testing Exception Handling ### Service Throws Expected Exception ```java @Test void shouldThrowExceptionWhenUserNotFound() { when(userRepository.findById(999L)) .thenThrow(new UserNotFoundException("User not found")); assertThatThrownBy(() -> userService.getUserDetails(999L)) .isInstanceOf(UserNotFoundException.class) .hasMessageContaining("User not found"); verify(userRepository).findById(999L); } @Test void shouldRethrowRepositoryException() { when(userRepository.findAll()) .thenThrow(new DataAccessException("Database connection failed")); assertThatThrownBy(() -> userService.getAllUsers()) .isInstanceOf(DataAccessException.class) .hasMessageContaining("Database connection failed"); } ``` ## Testing Complex Workflows ### Multiple Service Method Calls ```java @Test void shouldTransferMoneyBetweenAccounts() { Account fromAccount = new Account(1L, 1000.0); Account toAccount = new Account(2L, 500.0); when(accountRepository.findById(1L)).thenReturn(Optional.of(fromAccount)); when(accountRepository.findById(2L)).thenReturn(Opt