Groovy/Spock中的_._是什么意思?

5
我在几个Spock规范的源代码中看到了_._。有人知道这是什么意思吗?例如:
def "test something"() {
    given:
    someClass = Mock(SomeClass)

    and:
    1 * someClass.someMethod() >> returnSomething
    0 * _._

    when:
    String str = someClass.someMethod().toString()

    then:
    str == 'returnedValue'
}

1
它似乎意味着“任何交互”。请参阅https://code.google.com/p/spock/wiki/Interactions。 - Robert Harvey
1个回答

16

_ 就像一个通配符。

_.someMethod()

意思是在任何模拟对象上调用someMethod方法,同样适用于此。

myDomain._

表示对myDomain调用的任何内容。

按照这个逻辑,_._表示对任何模拟对象调用的内容。如果你不想再调用更多方法,这可能非常有用:

0 * _._

额外阅读

您应该阅读文档,以获取有关可以使用_的更多信息的内容。


哦,感谢您的快速回复。在我提供的示例中,我们为模拟对象的一个方法定义了所需的行为。并且期望它被调用一次,因此是 1 *。但是接下来的一行中有 _._。这是否意味着 0 * _._ 表示不会调用任何其他类的其他方法? - aa8y
2
0 * _._ 的意思就是你所写的。一些开发者会在测试方法的最后加上它,以确保没有其他交互发生。这不是一个好习惯。 - Opal
2
因为当您以这种方式开发测试时,它们就会被“固定”。例如,重构和引入代码更改变得困难,因为您引入了在编写测试时未考虑到的新交互 - 结果失败,尽管合同仍然有效。 - Opal
2
0 * _._ 可以缩写为 0 * _。详细解释请参见 http://docs.spockframework.org。 - Peter Niederwieser
我不同意Opal的观点。严格模拟是完全相关的。添加新的模拟调用可能会改变合同。有人无意中将“repository.deleteAllData();”复制到方法中。太好了。所有数据都丢失了,但测试仍然有效。干得好!每个模拟调用在每个测试中都被检查是非常重要的。 “0 * _”可以帮助实现这一点。 - Sven Döring
1
@SvenDöring 我认为这是情境相关的。我尽量避免交互检查,因为它可能会使测试变得非常脆弱,但我同意你的观点。成本与价值之间的权衡吧。 - christopher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接