unit-test-service-layer by giuseppe-trisciuoglio/developer-kit
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill unit-test-service-layer提供使用 Mockito 对 @Service 类进行单元测试的模式。模拟仓库调用,验证方法调用,测试异常场景,并模拟外部 API 响应。无需 Spring 容器或数据库即可实现快速、隔离的测试。
@Service 类中的业务逻辑遵循以下工作流程使用 Mockito 测试服务层,包括验证检查点:
使用 @ExtendWith(MockitoExtension.class) 启用 Mockito 注解。
@Mock 和 @InjectMocks 声明模拟对象使用 @Mock 标注依赖项(仓库、客户端),使用 @InjectMocks 标注待测试的服务。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
Arrange(准备):创建测试数据并使用 when().thenReturn() 配置模拟返回值。
Act(执行):执行待测试的服务方法。
Assert(断言):
verify() 验证模拟交互使用 when().thenThrow() 配置模拟对象抛出异常。
验证检查点:验证异常类型和消息
mvn test 或 gradle testmvn test jacoco:report@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);
}
}
@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");
}
如需更多模式(多个依赖项、参数捕获器、异步服务、InOrder 验证),请参阅 references/examples.md。
@ExtendWith(MockitoExtension.class) 实现 JUnit 5 集成expectedUser、actualUser、captor@Spy;部分模拟更难理解和维护。any()、eq())不能与同一存根中的实际值混合使用。每周安装量
368
代码仓库
GitHub 星标数
173
首次出现时间
2026年2月3日
安全审计
安装于
claude-code288
opencode281
gemini-cli280
cursor275
codex272
github-copilot259
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.
@Service classesFollow this workflow to test service layer with Mockito, including validation checkpoints:
Use @ExtendWith(MockitoExtension.class) to enable Mockito annotations.
@Mock and @InjectMocksUse @Mock for dependencies (repositories, clients) and @InjectMocks for the service under test.
Arrange : Create test data and configure mock return values using when().thenReturn().
Act : Execute the service method being tested.
Assert :
verify()Configure mocks to throw exceptions with when().thenThrow().
Validation checkpoint : Verify exception type and message
mvn test or gradle testmvn test jacoco:report@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);
}
}
@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.
@ExtendWith(MockitoExtension.class) for JUnit 5 integrationexpectedUser, actualUser, captor@Spy; partial mocking is harder to understand and maintain.any(), eq()) cannot be mixed with actual values in the same stub.Weekly Installs
368
Repository
GitHub Stars
173
First Seen
Feb 3, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code288
opencode281
gemini-cli280
cursor275
codex272
github-copilot259
xdrop 文件传输脚本:Bun 环境下安全上传下载工具,支持加密分享
20,700 周安装