org.mockito.exceptions.misusing.WrongTypeOfReturnValue,同时在groovy中使用mockito从“间谍”对象存根函数

问题描述

我遇到了这个问题,花费了我足够的时间,所以我决定在这里咨询专家。 一些上下文.. 我有一个 Jenkins 共享库,其中包含一些 groovy 类,我正在使用 JenkinsPipelineUnit 框架编写一些单元测试。我使用普通的 junit 进行测试,所以没有什么特别的。 基本上我有一个 groovy 类如下:

class MyClass {
    // In reality,`run` is object from the final class WorkflowRun but in the tests,I pass here a dummy map with the important fields
    def run

    MyClass(def run) {
        this.run = run
    }

    boolean somethingExists() {
        // some code here that does some stuff on `run` and return a boolean
    }

    String doSomething() {
        if(somethingExists()) {
            // do something with it.
            return "foo"
        } else {
            // do something else
            return "bar"
        }
    }
}

上面的代码很简单,我正在为 doSomething() 函数编写以下测试,而无需模拟 somethingExists() 的所有内部结构。

@Test
void testDoSomething() {
    Map run = [number: 1]
    MyClass mc = spy(new MyClass(run))
    // The problem is with the next line.
    doReturn(true).when(mc).somethingExists()

    assertTrue(mc.somethingExists())
    assertEquals("foo",mc.doSomething())
}

请注意,我不能模拟 WorkflowRun 类,因为它是最后一个类,老实说我不关心它,因为我需要测试 doSomething() 中的逻辑而不是 {{1} } 会检查 somethingExists() 对象上的一些 Jenkins 内部结构。因此,我决定“监视”被测对象 run 并使其在调用 mc 时返回一个简单的 truefalse 以避免对运行对象。 根据 Mockito 的文档,当我使用 spy 函数时,我应该像使用 somethingExists() 那样使用存根格式,这与 doReturn(true).when(mc).somethingExists() 的其他格式不同,因为这实际上会在尝试执行存根。

错误信息: 当我调用 when(mc.somethingExists()).thenReturn(true) 时,出现以下错误

doReturn(true).when(mc).somethingExists()

请注意,我没有并行运行测试(实际上,在重现问题时,我只运行了此测试)并且我遵循了建议的存根规则。 起初我认为这是因为 org.mockito.exceptions.misusing.WrongTypeOfReturnValue: Boolean cannot be returned by getMetaClass() getMetaClass() should return MetaClass *** If you're unsure why you're getting above error read on. Due to the nature of the syntax above problem might occur because: 1. This exception *might* occur in wrongly written multi-threaded tests. Please refer to Mockito FAQ on limitations of concurrency testing. 2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method. at org.codehaus.groovy.runtime.callsite.CallSiteArray.createPogoSite(CallSiteArray.java:140) at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallSite(CallSiteArray.java:158) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130) at MyClassTest.testDoSomething(MyClassTest.groovy:37) ... 返回的是原始类型而不是对象,所以我用 doReturn(true) 替换了它,但我仍然遇到相同的错误。 当我用 doReturn(Boolean.FALSE) 替换 doReturn(true).when(mc).somethingExists() 行时,它失败了,因为它正在调用我认为预期的实际函数 when(mc.somethingExists()).thenReturn(true)。另一方面,当我用一个简单的 mc.somethingExists() 替换 somethingExists() 函数的全部内容时,令人惊讶的是,格式 return false 仍然失败,但是另一种格式 doReturn(true).when(mc).somethingExists() 起作用了我很惊讶,因为这种格式不适用于间谍对象。

任何线索我可能做错了什么?我花了很多时间试图找出问题所在。 提前致谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)