Mockito如何测试方法内部创建的实例是否调用了目标方法
实现
verify(obj).callsMethod()调用校验的方案 你要实现的方法调用校验本质是验证目标类实例的方法调用行为,Kotlin生态下最常用的方案是使用Mock测试框架,以MockK为例的实现步骤如下:
- 先做依赖解耦:原方法中
Obj实例是方法内部直接创建的,测试时无法替换为可观测的测试实例,需要先调整代码结构把依赖外提:
// 调整后的方法,支持外部传入Obj实例,默认值保留原有逻辑不影响业务调用 fun method(obj: Obj = Obj()) { obj.callsMethod() obj.callsOtherMethod() }
- 测试项目引入MockK依赖后,编写测试用例即可实现和需求一致的校验逻辑:
import io.mockk.mockk import io.mockk.verify @Test fun `验证callsMethod被正常调用`() { // 构造Mock的Obj实例,relaxed参数表示不需要提前定义所有方法的桩实现 val mockObj = mockk<Obj>(relaxed = true) // 调用被测方法传入Mock实例 method(mockObj) // 校验callsMethod恰好被调用1次,语法和你预期的`verify`用法对齐 verify(exactly = 1) { mockObj.callsMethod() } }
其他可选测试方案
除了Mock框架之外,还可以根据业务场景选择以下测试方案:
- 状态校验法:如果
callsMethod调用会改变Obj实例的内部状态、或者产生可观测的副作用,可以直接校验最终状态值,不需要引入Mock框架。比如callsMethod会修改Obj的callCount字段,测试时直接传入真实Obj实例,调用后判断obj.callCount == 1即可。 - 伪造实现(Fake)方案:手动实现
Obj的测试子类,重写目标方法内部记录调用次数,测试时传入伪造实例校验计数即可,适合不想引入第三方Mock框架的场景:
// 自定义的测试用伪造实现 class FakeObj : Obj() { var callsMethod调用次数 = 0 override fun callsMethod() { callsMethod调用次数++ // 如需保留原有逻辑可以加super.callsMethod(),不需要可省略 } } // 测试代码 @Test fun `用伪造实现验证callsMethod调用`() { val fakeObj = FakeObj() method(fakeObj) assert(fakeObj.callsMethod调用次数 == 1) }
- 输出校验法:如果
callsMethod调用后会产生日志输出、文件写入、外部接口调用等可观测输出,可以直接校验这些输出是否符合预期,不需要直接校验方法调用行为。 - 集成测试方案:不单独测试该方法,将方法和其依赖的
Obj作为整体测试,校验整条链路的最终输出是否符合预期,适合逻辑简单、依赖少的业务场景。
内容的提问来源于stack exchange,提问作者user16976904
相关产品推荐
相关产品推荐

