如何使用 Mockk 设置默认应答策略

问题描述 投票:0回答:2

在 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
类,但我没有看到一个明显的方法来创建一个模拟,除了作为默认答案策略。

java unit-testing kotlin mockito mockk
2个回答
1
投票

如果我理解正确的话,你需要一个模拟,只要返回类型为

String
,就返回方法名称和参数,否则返回默认值。

您的

when
语句的第二个分支可以通过轻松的模拟轻松实现,即用
mockk(YourClass::class, relaxed = true)
模拟您的类或用
@RelaxedMockK
而不是
@MockK
注释您的模拟。

对于第一个分支,mockk 目前不支持存根所有具有返回类型的方法:我认为实现这种行为的唯一方法就是这样做

every { 
    yourMock.method(any())
} answers { 
    method.name + args.joinToString(" ") 
}

对于模拟类中的每个方法。

mockk
函数添加参数来定义覆盖
DefaultAnswerer
的策略应该不会太难,我很乐意查看有关它的 PR。


0
投票

现在可以使用 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/ 了解更多示例。

© www.soinside.com 2019 - 2024. All rights reserved.