6

Does anyone know how to capture an argument sent to an OCMock object?

id mock = [OCMockObject mockForClass:someClass]
NSObject* captureThisArgument;
[[mock expect] foo:<captureThisArgument>]

[mock foo:someThing]
GHAssertEquals[captured, someThing, nil];

How do I go about validating the argument to foo? I'm happy to do it within a block in the mock definition too, but if I could get the object out so that I can assert on feature of it later that would be brilliant.

Is this possible with OCMock?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Dr Joe
  • 718
  • 5
  • 19

2 Answers2

12

If you want to validate your parameter maybe you can do it directly while you are setting your stub with something like :

id mock = [OCMockObject mockForClass:someClass];
NSObject* captureThisArgument;
[[mock expect] foo:[OCMArg checkWithBlock:^(id value){ 
    // Capture argument here...
}]];

Regards, Quentin A

Titouan de Bailleul
  • 12,920
  • 11
  • 66
  • 121
Quentin
  • 1,741
  • 2
  • 18
  • 29
  • I like this. It's similar to how I would go about mocking with a hancrest matcher in groovy. Thanks :). – Dr Joe Apr 28 '12 at 19:52
4

You can stub the call and pass it to a block that verifies it:

NSObject *expected = ...;

id mock = [OCMockObject mockForClass:someClass]
void (^theBlock)(NSInvocation *) = ^(NSInvocation *invocation) {
    NSObject *actual;
    [invocation getArgument:&actual atIndex:2];
    expect(actual).toEqual(expected);   
};
[[[mock stub] andDo:theBlock] foo:[OCMArg any]];

[mock foo:expected];

There's also a callback version of this, but the control flow gets more complex, as you need a state variable that's visible to both your test and the verification callback:

[[[mock stub] andCall:@selector(aMethod:) onObject:anObject] someMethod:someArgument]
Christopher Pickslay
  • 17,523
  • 6
  • 79
  • 92
  • 1
    Thanks. @Quentin's answer was the concise one I was hoping for, but I really appreciate your example too. It's good to have an example of how to validate multiple arguments at mocking time. (I'd throw assertions in theBlock if anything wasn't right). – Dr Joe Apr 28 '12 at 19:55
  • The first two arguments of an NSInvocation are reserved for self and _cmd; the "first" argument to a method is at index 2. – titaniumdecoy Nov 13 '13 at 22:00