Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validating call arguments with a closure when stubbing return value

Tags:

spock

I have a question about validating arguments in a mock call with a closure. Sometimes I do this:

customerRepository.save({ Customer customer ->
        assert ...
        assert ...
    }) >> { ... some return value ... }

etc. i.e. multiple (but not too many) asserts in the closure, and also want to stub the call to return something. What I found out is that the code above doesn't work, I need to return a truthy value from the closure, otherwise the object I want to return is not returned and the test will fail somewhere else.

I don't think this is documented, could anybody say what the rules here are exactly?

Edit: actually, I've just checked and I need to return a truthy value even if I don't stub the return value.

like image 965
wujek Avatar asked Dec 15 '22 04:12

wujek


1 Answers

So far i know two options for validating arguments. Either match the arguments in-place which does not require asserts:

then:
1 * customerRepository.save({ it.id == 1 && it.name == "joe" }) >> returnValue

However, this will give you "too few invocations" if the validation fails which I find misleading in some cases and usually harder to debug.

Alternatively, match all arguments and assert in the implementation:

then:
1 * customerRepository.save(_) >> { Customer customer ->
    assert customer.id == 1
    assert customer.name == "joe"

    return returnValue
}

This will give you very descriptive assertion errors.

like image 65
laenger Avatar answered Apr 26 '23 19:04

laenger