在 Mockito 中,我可以创建类的模拟,并为该模拟的任何函数调用指定默认答案,如下所示:
whenever(this.strings).thenReturn(mock(StringProvider::class.java, StringProviderAnswer()))
答案可能在哪里
class StringProviderAnswer : Answer<Any?> {
private val delegate = Mockito.RETURNS_DEFAULTS!!
override fun answer(invocation: InvocationOnMock?): Any? {
val invocationMethodReturn = invocation?.method?.returnType
val stringType = String::class.java
return when (invocationMethodReturn) {
stringType -> invocation.method?.name.toString() + invocation.arguments.joinToString()
else -> delegate.answer(invocation)
}
}
}
所以我可以非常详细地存根一个类的所有函数。 有没有办法用 Mockk 来做到这一点? 我看到有一个
Answer
类,但我没有看到一个明显的方法来创建一个模拟,除了作为默认答案策略。
如果我理解正确的话,你需要一个模拟,只要返回类型为
String
,就返回方法名称和参数,否则返回默认值。
您的
when
语句的第二个分支可以通过轻松的模拟轻松实现,即用 mockk(YourClass::class, relaxed = true)
模拟您的类或用 @RelaxedMockK
而不是 @MockK
注释您的模拟。
对于第一个分支,mockk 目前不支持存根所有具有返回类型的方法:我认为实现这种行为的唯一方法就是这样做
every {
yourMock.method(any())
} answers {
method.name + args.joinToString(" ")
}
对于模拟类中的每个方法。
向
mockk
函数添加参数来定义覆盖 DefaultAnswerer
的策略应该不会太难,我很乐意查看有关它的 PR。
现在可以使用 reflective-mockk(mockk 的附加库)实现这一点。最干净的方法可能是只对返回字符串的方法进行存根。
val mock = reflectiveMockk<SomeObject> {
answerEveryCallIn(normalMemberFunctions.filterReturnType<String>()) {
method.name + args.joinToString()
}
}
或者,您可以为所有方法提供defaultAnswer,但是您需要考虑其他可能的返回类型...
val mock = reflectiveMockk<SomeObject> {
defaultAnswer {
when (method.returnType) {
String::class -> method.name + args.joinToString()
Unit::class -> Unit
else -> null // unsafe
}
}
}
请参阅 https://episode6.github.io/reflective-mockk/ 了解更多示例。