Is there any way to do mock argument capturing in Spock
Asked Answered
S

1

33

I have looked around and tried different things to no avail. The examples out there on the interwebs are few, and IMHO pretty simple. My use case:

(the 'itocNetworkHandler' below is the mock)

when: "we're doing stuff"
    StandardResponse response = cms.doCardStuff("123", "111", order)
....
then: "we get proper calls and response object"
    1 * cms.itocNetworkHandler.doNetworkCall(
            { it instanceof ReplacementRequestRecord
            }, StandardResponseRecord.class) >> record

I would like to store away the parameter ('it') to the "doNetworkCall" on the mock.

The reason i want the parameter is because the object i'm testing is supposed to take my in parameters, do stuff, create a new object and pass that one to my mock. I want to make sure that the created object looks the way its supposed to.

Pointers much appreciated.

Spoilage answered 2/5, 2013 at 5:54 Comment(2)
Why do you want to store the argument? What will you do with it?Apivorous
I clarified above why i need it.Spoilage
A
49

You can capture an argument as follows:

// must be declared before when-block (or inside Specification.interaction {})
def captured

when:
...

then:
1 * mock.doNetworkCall(...) >> { record, recordClass -> 
    // save the argument
    captured = record
    ...
}
// use the saved argument
captured == ...

That said, often there is a simpler solution such as checking the expected record right in the argument constraint (e.g. ...doNetworkCall( { it == ... } )).

Apivorous answered 2/5, 2013 at 7:29 Comment(5)
Thanks, works. The reason i dont want it in "it ==" etc. is that i want to lots of checks, and i think its much tidier to have all asserts in the end, if you see what i mean.Spoilage
You could put the checks into a helper method, and call the helper method from the argument constraint.Apivorous
Yeah, thats a possibility. I think i like them in the end though. It feels a little bit "sneaky" to do the asserts within the parameter block, for readability i like them in the end. Or perhaps i'm just not used to the lingo.Spoilage
I have found it impossible to access the captured argument outside of the closure, regardless of where the variable is defined.Pompidou
I couldn't figure out how to break up the arguments in the closure as in the example code. I had to do 1 * mock.doNetworkCall(_) >> { arguments -> captured = arguments.get(0)}Washerwoman

© 2022 - 2024 — McMap. All rights reserved.