Stub a Method That Returns a BOOL with OCMock
Asked Answered
P

3

30

I'm using OCMock 1.70 and am having a problem mocking a simple method that returns a BOOL value. Here's my code:

@interface MyClass : NSObject
- (void)methodWithArg:(id)arg;
- (BOOL)methodWithBOOLResult;
@end
@implementation MyClass
- (void)methodWithArg:(id)arg {
    NSLog(@"methodWithArg: %@", arg);
}
- (BOOL)methodWithBOOLResult {
    NSLog(@"methodWithBOOLResult");
    return YES;
}
@end

- (void)testMock {
    id real = [[[MyClass alloc] init] autorelease];
    [real methodWithArg:@"foo"];
    //=> SUCCESS: logs "methodWithArg: foo"

    id mock = [OCMockObject mockForClass:[MyClass class]];
    [[mock stub] methodWithArg:[OCMArg any]];
    [mock methodWithArg:@"foo"];
    //=> SUCCESS: "nothing" happens

    NSAssert([real methodWithBOOLResult], nil);
    //=> SUCCESS: logs "methodWithBOOLResult", YES returned

    BOOL boolResult = YES;
    [[[mock stub] andReturn:OCMOCK_VALUE(boolResult)] methodWithBOOLResult];
    NSAssert([mock methodWithBOOLResult], nil);
    //=> FAILURE: raises an NSInvalidArgumentException:
    //   Expected invocation with object return type.
}

What am I doing wrong?

Pervade answered 5/12, 2010 at 2:55 Comment(0)
3
65

You need to use andReturnValue: not andReturn:

[[[mock stub] andReturnValue:OCMOCK_VALUE(boolResult)] methodWithBOOLResult];
3d answered 5/12, 2010 at 3:49 Comment(0)
J
5

Hint: andReturnValue: accepts any NSValue -- especially NSNumber. To more quickly stub methods with primitive/scalar return values, skip the local variable declaration altogether and use [NSNumber numberWithXxx:...].

For example:

[[[mock stub] andReturnValue:[NSNumber numberWithBool:NO]] methodWithBOOLResult];

For auto-boxing bonus points, you can use the number-literal syntax (Clang docs):

[[[mock stub] andReturnValue:@(NO)] methodWithBOOLResult];
[[[mock stub] andReturnValue:@(123)] methodWithIntResult];
[[[mock stub] andReturnValue:@(123.456)] methodWithDoubleResult];
etc.
Jordan answered 11/12, 2013 at 23:22 Comment(1)
Newer versions of OCMock should let OCMOCK_VALUE work on constants as well; OCMOCK_VALUE(NO), @NO, and @(NO) should all work.Guimar
S
2

I'm using version 3.3.1 of OCMock and this syntax works for me:

SomeClass *myMockedObject = OCMClassMock([SomeClass class]);
OCMStub([myMockedObject someMethodWithSomeParam:someParam]).andReturn(YES);

See the OCMock Reference page for more examples.

Squeteague answered 15/12, 2016 at 11:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.