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.

Mathias
  • 3,879
  • 5
  • 36
  • 48

1 Answers1

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 == ... } )).

Peter Niederwieser
  • 121,412
  • 21
  • 324
  • 259
  • 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. – Mathias May 02 '13 at 07:41
  • You could put the checks into a helper method, and call the helper method from the argument constraint. – Peter Niederwieser May 02 '13 at 07:44
  • 1
    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. – Mathias May 02 '13 at 07:52
  • I have found it impossible to access the captured argument outside of the closure, regardless of where the variable is defined. – orbfish Jun 21 '16 at 18:34
  • 1
    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)}` – Joman68 Aug 29 '19 at 00:22