问题描述
我遇到了这个问题,花费了我足够的时间,所以我决定在这里咨询专家。 一些上下文.. 我有一个 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
时返回一个简单的 true
或 false
以避免对运行对象。
根据 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 (将#修改为@)