Question

Intro:

I have the tool (Xcode 5.0.2), library (OCMock 2.2.1) and test (XCTest) setup mentioned in the title of this question.

Category:

I have a category on NSObject with a class method like this:

+ (BOOL) hasDeclaredPropertyWithName: (NSString*) property;

Issue with OCMock and XCTest framework?:

Now i have a simple test set-up where I'm mocking a simple value object, like this: (mocking value objects is a test smell, I know. but this is just for illustration purpose.)

- (void) testFoo {
     id mock = [OCMockObject mockForClass: [TestObject class]];
     [[[mock stub] andReturn: NO] hasDeclaredPropertyWithName: @"propertyX"];
     [mock hasDeclaredPropertyWithName: @"propertyX"];
}

When the 3rd line of the test method testFoo is executed, I end up with the error:

-[NSProxy doesNotRecognizeSelector:hasDeclaredPropertyWithName:] called!

Question:

Why mocking a class method seems impossible with OCMock (At least with my setup)?

If i make hasDeclaredPropertyWithName to an instace method like

- (BOOL) hasDeclaredPropertyWithName: (NSString*) property;

everything's working just fine!

Can someone explain this OCMock deficiency to me? Or do I have a major missconception regarding Objective-C here? :)

Is the category maybe causing headaches to the runtime and/or OCMock? Btw., I didn't try this test with a class method inside TestObject directly!

Was it helpful?

Solution

Ok, so first the base case, where we are mocking a category class method:

Some class I had laying around for testing, Huzzah:

@interface Huzzah : NSObject
+ (void)doClass;
+ (void)doClass2;
+ (void)doClass3;
- (void)doInstance;
@end

I created a category:

@interface Huzzah (Cat)
+ (BOOL)hasX:(NSString *)x;
@end

@implementation Huzzah (Cat)
+ (BOOL)hasX:(NSString *)x
{
    return YES;
}
@end

In my test:

#import "Huzzah+Cat.h"
- (void)testHuzzahCat
{
    id mock = [OCMockObject mockForClass:Huzzah.class];
    [[[mock stub] andReturnValue:OCMOCK_VALUE((BOOL){NO})] hasX:OCMOCK_ANY];
    NSLog(@"hasX: %i", [Huzzah hasX:@"DoYouHas?"]);
}

Output: hasX: 0

Now let's try a category on NSObject:

@interface NSObject (Cat)
+ (BOOL)hasY:(NSString *)y;
@end

@implementation NSObject (Cat)
+ (BOOL)hasY:(NSString *)y
{
    return YES;
}
@end

Our new test:

#import "NSObject+Cat.h"
- (void)testObjectCat
{
    id mock = [OCMockObject mockForClass:Huzzah.class];
    [[[mock stub] andReturnValue:OCMOCK_VALUE((BOOL){NO})] hasY:OCMOCK_ANY];
    NSLog(@"hasY: %i", [Huzzah hasY:@"DoYouHas?"]);
}

Results in: hasY: 0

Is it possible that the implementation of category is not getting compiled into your project?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top