如何在测试中使用Mockito或PowerMock来模拟Kotlin扩展函数?由于它们是静态解析的,所以应该将它们作为静态方法调用进行测试还是作为非静态方法?
data class Obj(val value: Int)
class Ext {
fun Obj.extensionFunc() = value + 5
}
with(mockk<Ext>()) {
every {
Obj(5).extensionFunc()
} returns 11
assertEquals(11, Obj(5).extensionFunc())
verify {
Obj(5).extensionFunc()
}
}
data class Obj(val value: Int)
// declared in File.kt ("pkg" package)
fun Obj.extensionFunc() = value + 5
mockkStatic("pkg.FileKt")
every {
Obj(5).extensionFunc()
} returns 11
assertEquals(11, Obj(5).extensionFunc())
verify {
Obj(5).extensionFunc()
}
mockkStatic(Obj::extensionFunc)
val Obj.squareValue get() = value * value
mockkStatic(Obj::squareValue)
import io.mockk.verify as verifyMockk
。 - MicermockkStatic(Obj::extensionFunction.declaringKotlinFile.qualifiedName!!)
来代替指定文件名为字符串。这样做可以避免在文件重命名或移动时出现奇怪的错误。 - undefinedmockkStatic(Context::getActivity.declaringKotlinFile.qualifiedName!!) { your test code }
。在你的测试代码中,你可以为一个具体的实例模拟getActivity
,例如every { myContext.getActivity() } returns ...
,或者为任何实例模拟getActivity
,例如every { any<Context>().getActivity() } returns ...
。 - undefineddata class Bar(thing: Int)
class Foo {
fun Bar.bla(anotherThing: Int): Int { ... }
}
val bar = Bar(thing = 1)
val foo = mock<Foo>()
with(foo) {
whenever(any<Bar>().bla(any()).doReturn(3)
}
verify(foo).apply {
bar.bla(anotherThing = 2)
}
class FilenameKt { public static ReturnType extensionName(Receiver receiver, Params otherParams)...}
。请注意,这是一个翻译,不包括解释或其他内容。 - Kraiden@file:JvmName(name = "ExtensionUtils")
package myproject.extension
...
为了快速编码,我创建了带有不同扩展名的文件模拟:
object FastMock {
fun extension() = mockkStatic("myproject.extension.ExtensionUtils")
fun listExtension() = mockkStatic("myproject.extension.ListExtensionUtils")
}
在测试中调用此函数:
FastMock.listExtension()
every { itemList.move(from, to) } returns Unit
ContextExt.kt
文件中给出一个顶级(意味着不在类中声明的)扩展方法,例如:Context.doSomething(param1: Int, param2: String = "default") : Int {
// Does something that wouldn't work in your test environment
}
MyTestClass {
companion object {
private const val MOCKED_VALUE = 10
}
...
@Before
fun before() {
mockkStatic("com.my.package.ContextExtKt")
every { any<Context>().doSomething(any(), any()) } returns MOCKED_VALUE
}
}
mockkStatic(YourClass::extensionFunction)
every { any<YourClass>().extensionFunction() } returns YOUR_MOCKED_DATA
e.g
fun String.doSomething() = "SOMETHING"
@Test
fun `test extension functions`() {
mockkStatic(String::doSomething)
every { any<String>().doSomething() } returns YOUR_MOCKED_DATA
}