unit-testing - MockK - 在顶级 val 上调用模拟/间谍顶级扩展方法
问题描述
在下面的 MWE 中,我试图验证调用是否baz()
也会调用另一个对象的方法。但是,我似乎无法模拟/监视该对象。
MWE:
package com.example
import io.mockk.every
import io.mockk.mockkStatic
import io.mockk.spyk
import io.mockk.verify
import org.junit.jupiter.api.Test
class FooBarTest {
@Test
fun `top level fun baz() calls theVal_bar()`() {
mockkStatic("com.example.FooBarTestKt")
val spy = spyk(theVal, name = "Hello, Spy!")
every { theVal } returns spy
// Should call bar() on the spy, but note that the spy's name is not printed
baz()
verify { spy.bar() }
}
}
class Foo
fun Foo.bar() = println("Foo.bar! name = $this")
val theVal = Foo()
fun baz() = theVal.bar()
这失败了,因为调用theVal.bar()
获取val
初始化值而不是模拟值spy
。
如何在不更改顶级属性定义的情况下强制使用间谍?换句话说:我需要一个顶级的“常量”,但我也想模拟它。我可以使用val theVal get() = Foo()
,它解决了这个问题,但它显着改变了代码,因为它Foo
每次都会替换实例。
使用的版本: - Kotlin 1.3.10 - MockK 1.8.13.kotlin13 - JUnit 5.3.1
错误:
java.lang.AssertionError: Verification failed: call 1 of 1: class com.example.FooBarTestKt.bar(eq(Foo(Hello, Spy!#1)))). Only one matching call to FooBarTestKt(static FooBarTestKt)/bar(Foo) happened, but arguments are not matching:
[0]: argument: com.example.Foo@476b0ae6, matcher: eq(Foo(Hello, Spy!#1)), result: -
解决方案
哦,当涉及到静态和对象模拟以及扩展函数时,这真是太疯狂了。为了生存,只需将扩展函数视为带有参数的静态函数。
检查,这是有效的,因为fooInstance
它只是作为第一个参数传递的对象:
mockkStatic("kot.TestFileKt")
baz()
val fooInstance = theVal
verify { fooInstance.bar() }
结合它不起作用:
verify { theVal.bar() }
因为它也是经过验证的。
这也将起作用(正如我所说Foo
的只是静态方法的第一个参数):
mockkStatic("kot.TestFileKt")
baz()
verify { any<Foo>().bar() }
推荐阅读
- sql-server - 在 SSMS 中保留 SET NOCOUNT 选项等
- python - InvalidSchema("没有为 '%s' 找到连接适配器" % url) 用于 skype url
- python - 考虑时间序列作为输入图像向量的 Keras 多标签时间序列分类
- matlab - MATLAB - 在 uint16 图像中未检测到 SURF 特征
- java - Select json column using JPA native query with MemSql
- python - How to sort first half in ascending and second half in descending order in python?
- javascript - 在 Vue.js 中将文件上传到 ftp 服务器
- python - 对字符串值使用 Struct.pack 格式
- android - 如何禁用主页和返回按钮?
- javascript - Add and delete row in the table