What does it mean by _._ in Groovy/Spock
Asked Answered
G

1

5

I have seen _._ in the source code of a few Spock Specs. Does anyone know what that means?

For example,

def "test something"() {
    given:
    someClass = Mock(SomeClass)

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

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

    then:
    str == 'returnedValue'
}
Gaddy answered 3/9, 2014 at 17:13 Comment(1)
It appears to mean "Any interaction." See code.google.com/p/spock/wiki/InteractionsBunny
B
17

_ is like a wildcard.

_.someMethod()

Means the method someMethod called on any mocked object, likewise

myDomain._

Means anything called on myDomain.

And following that logic _._ means anything called on any mock object. This can be useful if you don't want any more methods called:

0 * _._

Extra Reading

You should read the docs for some more information on the kinds of things _ can be used for.

Brainwashing answered 3/9, 2014 at 17:16 Comment(6)
Oh thanks for the quick response. In the example I provided, we define a desired behavior for a method of the mock object. And it is expected to be called once, therefore 1 *. But then there is _._ in the next line. Does that mean that 0 * _._ means that none of the other methods of any other class are to be called?Gaddy
0 * _._ means exactly what You wrote. Some developers add it at the very end of the test method to ensure no other interaction took place. This is not a good practice.Beech
Because when You develop the tests this way they will get 'fixed'. E.g. refactoring and introducing changes to code is difficult because You introduce new interactions that were not taken into account when test was written - it fails in a result despite the fact that the contract is still kept.Beech
0 * _._ can be abbreviated to 0 * _. A detailed explanation can be found at docs.spockframework.org.Apropos
I disagree with Opal. Strict mocking is totally relevant. Adding new mock calls might change the contract. Someone copies repository.deleteAllData(); by accident into the method. Great. All data is lost, but the test still works. Good work! It's very important that every mock call is checked on every tests. The 0 * _ helps with that.Covering
@SvenDöring I think it's contextual. I try to avoid interaction checking because of how brittle it can make the tests, but I agree with your point. Cost vs Value I suppose.Brainwashing

© 2022 - 2024 — McMap. All rights reserved.