如何为带依赖的MyServiceImpl服务编写单元测试?
如何Mock Loader来测试MyServiceImpl?
背景代码
服务接口MyService
interface MyService { int getItem(); }
实现类MyServiceImpl
@Service class MyServiceImpl implements MyService { public MyServiceImpl(List<Loader> loaders) { } public int getItem() { Loader loader = getTheLoader(); return loader.getItem(); } }
测试需求
我要对MyServiceImpl做单元测试,希望测试它的真实实现逻辑(不止是转发getItem调用),但不想用真实的Loader(避免变成集成测试)。目前我尝试传入自定义的TestLoader实例,但需要捕获getItem的调用次数这类信息,所以应该用Mock的Loader替代,但不知道怎么Mock Loader<String, Object>并覆写getItem方法。
解决方案:用Mockito实现Mock
1. 引入Mockito依赖(以Maven为例)
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency>
2. 编写测试类
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import static org.mockito.Mockito.*; @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MyServiceTests { private MyService myService; // 创建Loader<String, Object>的Mock实例 @Mock private Loader<String, Object> mockLoader; @BeforeAll void init() { // 初始化所有Mock对象 MockitoAnnotations.openMocks(this); // 把Mock的Loader传入真实的MyServiceImpl实例 myService = new MyServiceImpl(List.of(mockLoader)); // 预设mockLoader的getItem方法返回值(按需设置) when(mockLoader.getItem()).thenReturn(100); } @Test void testGetItem() { // 调用被测试方法 int result = myService.getItem(); // 验证mockLoader的getItem是否被调用了1次 verify(mockLoader, times(1)).getItem(); // 验证返回值符合预期 assert result == 100; } }
核心要点
- 用
@Mock注解直接生成Loader的Mock对象,不用自己写TestLoader子类 - 通过
when(...).thenReturn(...)预设Mock方法的返回值,模拟Loader的行为 - 用
verify(...)可以轻松验证方法调用次数、参数等,满足你捕获调用信息的需求 - 始终使用真实的
MyServiceImpl实例,确保测试的是它的真实业务逻辑,同时完全隔离了真实Loader的依赖
内容的提问来源于stack exchange,提问作者SledgeHammer
相关产品推荐
相关产品推荐

