How do I stub a class method with OCMockito?

2.3k Views Asked by At

The OCMockito documentation claims it's possible to mock class objects, but I'm damned if I can work out how. The following test fails with Expected "Purple" but was "":

- (void)testClassMethodMocking
{
    Class stringClassMock = mockClass([NSString class]);
    [given([stringClassMock string]) willReturn:@"Purple"];

    assertThat([NSString string], equalTo(@"Purple"));
}

If the answer to the abovelinked FAQ section "How do you mock a class object?" does not imply it's possible stub the return value of a class method, what is it used for?

EDIT:

Of course the above is a degenerate example, the real [NSString string] call is inside the method under test:

- (NSString *)methodThatCallsAClassMethod
{
    return [NSString string];
}

... making the assert above look like:

assertThat([testedObject methodThatCallsAClassMethod], equalTo(@"Purple"));

So the above just flat-out won't work? How do I achieve what I want to do here, then?

1

There are 1 best solutions below

2
On

Your assertion statement is using NSString directly. Use the mock instead:

assertThat([stringClassMock string], equalTo(@"Purple"));

In other words, the mock isn't swizzling the actual NSString. Rather, it's a stand-in for it.

EDIT:

In your edited example, your "methodThatCallsAClassMethod" has a dependency on NSString. If you wanted to replace that, you either need to inject the class, or Subclass and Override Method.

Injection:

return [self.stringClass string];

Then you can set the stringClass property to a mock.

Subclass and Override Method:

@interface TestingFoo : Foo
@end

@implementation @TestingFoo

- (NSString *)methodThatCallsAClassMethod
{
    // return whatever you want
}

@end