-
moreInterfaces
: 让这个mock出来的对象实现这些声明的接口 -
relaxUnitFun
:和relaxed
差不多,但是只针对于 返回值是Unit 的方法, 后续会讲解一下 -
block
: 该语句块表示你在创建完 mock 对象后的操作,相当于.also{ ... }
语句
2.3.2 relaxed 和 relaxUnitFun
在 mock 一个对象时,这两个参数的意义是什么呢? 举个例子,我现在有一个被测类 Car,它依赖于一个 Engine:
class Car(private val engine: Engine) {
fun getSpeed(): Int {
return engine.getSpeed()
}
}
class Engine {
fun getSpeed(): Int {
return calSpeed()
}
private fun calSpeed(): Int {
return 30
}
}
我们要测试 getSpeed()
,它依赖于 Engine 里的方法,所以我们需要 mockk 一下 Engine,那么写下下面的测试方法:
fun testCar() {
// mock engine对象
val engine = mockk()
val car = Car(engine)
// 这里是私有方法设置监听的写法:
every { engine"calSpeed" } returns 30
val speed = car.getSpeed()
assertEquals(speed, 30)
}
但是这里我们报了一个错误: io.mockk.MockKException: no answer found for: Engine(#1).getSpeed()
这是因为mockk是严格去执行每个方法,而 Engine虽然mock了出来,但是mockk并不知道 Engine.getSpeed()
需不需要往下执行,所以它抛出了一个错误。
这个时候,你有两种解决方案。
方案一:将 Engine 的构建从 mock 改成 spy,因为spy可以真实模拟对象行为: engine = spyk<Engine>()
方案二:抛弃 calSpeed 方法, 使用 every { engine.getSpeed() } returns 30
方案三:在 mock Engine 时, 将 relaxed
置为true, engine = mockk<Engine>(relaxed = true)
这就是 relaxed
的作用,它真实模拟mock对象的所以方法,产生依赖。
而 relaxe