2

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?

Robert Atkins
  • 23,528
  • 15
  • 68
  • 97

1 Answers1

4

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
Jon Reid
  • 20,545
  • 2
  • 64
  • 95
  • I would like to know the answer to Robert's edit as well. The class under test uses NSString class method. It's not injected. If no swizzling in place then you couldn't possibly test the method under test, could you? – huggie Nov 20 '13 at 02:35
  • @huggie That's correct. If you want to capture something, you either have to inject it, or subclass and override method. – Jon Reid Nov 20 '13 at 03:12