As a Java developer, I am currently struggling my way through iOS and Objective-C while developing an iPad app. My latest struggle with iOS and Objective-C was the combination of OCMock and XCTest. While the basics are quite similar to for instance Mockito and JUnit for Java, I ran into a few problems and distilled some tips and tricks from what I’ve learned.

Mock and verify a static method

- (void)setUp()
{
self.myMock = [OCMockObject mockForClass:[MyClass class]];
[[[self.myMock expect] andReturnValue:5] myStaticMethod:3];
}

Now, you can test your code that depends on this static method, knowing it will return 5 when argument 3 is passed.

- (void)testMyStaticMethod
{
XCTAssertEqual(5, [MyClass methodThatCallsMyStaticMethod:3]);
[self.myMock verify];
}

The verify method now verifies that methodThatCallsMyStaticMethod internally called myStaticMethod with argument 3.

Stop Mocking Static Methods!

- (void)tearDown
{
[self.myMock stopMocking];
}

In my case, the test with the mocked class ran before the unit test of this class itself. This resulted in OCMock generating a Thread 1: EXC_BAD_ACCESS (code=2, address=0x7fff5f3ffff8) in its removeForwarderForClassMethodSelector: method whenever I tried using the mocked static method in the actual unit test for that class.

Return Primitive Values

(5) equal to ([MyClass methodThatCallsMyStaticMethod:3]) failed: throwing “Return value does not match method signature; signature declares ‘q’ but value is ‘i’.”

If you modify your code to the following snippet, your code will work:

[[[self.myMock expect] andReturnValue:OCMOCK_VALUE((NSInteger){5})] myStaticMethod:3];

Any Argument for Primitives

[[[[self.myMock expect] ignoringNonObjectArgs] andReturnValue:OCMOCK_VALUE((NSInteger){5})] myStaticMethod:0];

The ignoringNonObjectArgs part simply tells OCMock to accept any primitive argument.

Use zero with ignoringNonObjectArgs

// Bad!
[[[[self.myMock expect] ignoringNonObjectArgs] andReturnValue:OCMOCK_VALUE((NSInteger){5})] myStaticMethod:4];
// Good!
[[[[self.myMock expect] ignoringNonObjectArgs] andReturnValue:OCMOCK_VALUE((NSInteger){5})] myStaticMethod:0];

Tech enthusiast

Tech enthusiast