I like the smell of Swift in the morning…

OCMock: signature declares ‘q’ but value is ‘i’

Posted: | Author: | Filed under: Objective-C | Tags: | No Comments »

When writing a test for a class using OCMock I ran into the following error message:

error: -[PXDItemsListView testListView] : failed: caught "NSInvalidArgumentException", "Return value does not match method signature; signature declares 'q' but value is 'i'."

The code that was causing this error was this:

OCMStub([self.dataSourceMock numberOfItems]).andReturn(4);

Which is a stub of the data source’s method:

- (NSInteger)numberOfItems;

And you do not get this error when you implement this method like this:

- (NSInteger)numberOfItems {
   return 4;

So why does the stubbing of this method create this error?

The reason is, that the implemented method does know it’s return type, so the 4 will automatically be typed to NSInteger. Which means that it will be of type int on 32-bit architectures and of type long on 64-bit architectures.

OCMock on the other hand has no idea what the return type of the 4 should be. It just sees the 4 and assumes that it is of type int. Regardless of the architecture. So when running this this on a 64-bit device you will get this error, because the stubbed method is supposed to return a long.

The fix for this is quite easy. You just have to be clear about the type of the value that your stub should return:

OCMStub([self.dataSourceMock numberOfTeasers]).andReturn((NSInteger)4);

Actually this is explicitly written down in the OCMock reference: “For methods that return primitive values it is important to use the right type of value.”

But, hey, who reads the f***ing manual, right?