如何Mock服务层方法 测试调用私有方法的服务层公共方法
核心问题解答
需要考虑私有方法xyz()使用的userRepository依赖。
单元测试的核心目标是验证对外暴露的public方法的行为符合预期,不需要主动调用私有方法、也不需要关注私有方法的实现逻辑,但私有方法中调用的外部依赖如果不做模拟,会触发真实的数据库存储操作,既不符合单元测试的隔离性要求,也会导致测试结果依赖外部环境的稳定性。
具体操作步骤(Spring Boot + Mockito 常规实现方案)
- 第一步:确认测试依赖引入,常规Spring Boot项目只要引入了
spring-boot-starter-test就内置了Mockito所需的所有组件,无需额外引入依赖。 - 第二步:搭建测试类基础结构,使用
@InjectMocks注解标注待测试的UserServiceImpl实例,使用@Mock注解标注要模拟的UserRepository依赖,启动测试时Mockito会自动将模拟好的依赖注入到待测试类中。 - 第三步:编写测试逻辑,在调用
abc()方法后,通过Mockito的验证逻辑判断userRepository的save方法是否按照预期被调用,包括调用次数、入参是否符合要求;如果save方法有返回值,也可以提前模拟返回值来验证后续逻辑。
代码示例
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.times; import static org.mockito.Mockito.verify; @ExtendWith(MockitoExtension.class) public class UserServiceImplTest { @Mock private UserRepository userRepository; @InjectMocks private UserServiceImpl userService; @Test public void testAbc() { // 构造业务所需的测试入参,根据实际业务替换即可 Object testObj = new Object(); // 调用待测试的public方法abc userService.abc(testObj); // 验证userRepository的save方法被调用1次,且入参符合预期 verify(userRepository, times(1)).save(testObj); } }
注:示例补全了原代码中省略的参数传递逻辑,和实际业务匹配即可。
注意事项
不要为了测试方便将私有方法改为public,也不要用反射强制调用私有方法,这类做法会破坏代码的封装性。单元测试只需要验证public方法的输入输出符合预期、外部依赖被正确调用即可,内部私有方法的实现属于类的内部细节,不需要单独测试。
内容的提问来源于stack exchange,提问作者Nisal Pubudu
相关产品推荐
相关产品推荐

