@hayfreed:其实我不喜欢推测,所以下次(或者这次,以防我猜错了)在 StackOverflow 上提问时,请提供的不仅仅是一组不连贯的代码 sn-ps。理想情况下,提供MCVE(请阅读!)。
让我们先创建一个 MCVE,好吗?
package de.scrum_master.stackoverflow.q62543765
class OtherClass {}
package de.scrum_master.stackoverflow.q62543765
class MyClass {
MyClass(Map args) {
assert args.firstArg
}
}
package de.scrum_master.stackoverflow.q62543765
import spock.lang.Specification
class MyClassTest extends Specification {
def "do not use mock"() {
when:
new MyClass([firstArg: new OtherClass(), secondArg: "foo"])
then:
noExceptionThrown()
when:
new MyClass([firstArg: null, secondArg: "foo"])
then:
thrown AssertionError
when:
new MyClass([secondArg: "foo"])
then:
thrown AssertionError
}
def "use mock"() {
when:
new MyClass([firstArg: Mock(OtherClass), secondArg: "foo"])
then:
noExceptionThrown()
}
}
此测试通过。但是如果我们将OtherClass 改为集合类型呢?
package de.scrum_master.stackoverflow.q62543765
class OtherClass extends ArrayList<String> {}
使用 mock 的特征方法 not 测试失败:
Expected no exception to be thrown, but got 'org.codehaus.groovy.runtime.powerassert.PowerAssertionError'
at spock.lang.Specification.noExceptionThrown(Specification.java:118)
at de.scrum_master.stackoverflow.q62543765.MyClassTest.do not use mock(MyClassTest.groovy:10)
Caused by: Assertion failed:
assert args.firstArg
| |
| []
['firstArg':[], 'secondArg':'foo']
at de.scrum_master.stackoverflow.q62543765.MyClass.<init>(MyClass.groovy:5)
at de.scrum_master.stackoverflow.q62543765.MyClassTest.do not use mock(MyClassTest.groovy:8)
所以你看到Groovy truth 不仅仅是一个空检查。例如。如果集合为空,集合类型也会为断言产生 false。
但回到你的问题。模拟测试怎么会失败?我最好的猜测是,没有看到您的 OtherClass 的代码,该类实现了一个 asBoolean 方法,如手册中有关 Groovy 真相的部分所述:
package de.scrum_master.stackoverflow.q62543765
class OtherClass {
boolean asBoolean(){
true
}
}
现在测试失败看起来很像你的:
Expected no exception to be thrown, but got 'org.codehaus.groovy.runtime.powerassert.PowerAssertionError'
at spock.lang.Specification.noExceptionThrown(Specification.java:118)
at de.scrum_master.stackoverflow.q62543765.MyClassTest.use mock(MyClassTest.groovy:28)
Caused by: Assertion failed:
assert args.firstArg
| |
| Mock for type 'OtherClass'
['firstArg':Mock for type 'OtherClass', 'secondArg':'foo']
at de.scrum_master.stackoverflow.q62543765.MyClass.<init>(MyClass.groovy:5)
at de.scrum_master.stackoverflow.q62543765.MyClassTest.use mock(MyClassTest.groovy:26)
你会如何解决这个问题?只需存根asBoolean 方法即可返回true:
def "use mock"() {
given:
def otherClass = Mock(OtherClass) {
asBoolean() >> true
}
when:
new MyClass([firstArg: otherClass, secondArg: "foo"])
then:
noExceptionThrown()
}