views:

201

answers:

1

I have a class that relies on NSUserDefaults that I'm trying to unit-test and I'm providing the NSUserDefaults as a mock into my test class. When running the test, I get the error:

OCMockObject[NSUserDefaults]: unexpected method invoked: dictionaryForKey:@"response"

I'm trying to mock this instance method of the NSUserDefaults class:

- (NSDictionary *)dictionaryForKey:(NSString *)defaultName;

using the call format:

[[[mockClass stub] andReturn:someDictionary] dictionaryForKey:@"aKey"]

to tell the mock that it needs to expect the dictionaryForKey method. But somehow, this isn't recorded or isn't the right thing to tell the mock to expect since the error tells me that mock never knew to expect the 'dictionaryForKey' call.

The way I'm invoking the stub's andReturn seems very similar to this question but in that one, the poster says they're getting a return value. My test case:

-(void)testSomeWork
{
    id userDefaultsMock = [OCMockObject mockForClass:[NSUserDefaults class]];       
    MyClass *myClass = [[MyClass alloc] initWith:userDefaultsMock];

    NSDictionary *dictionary = [NSDictionary dictionary];

    [[[userDefaultsMock stub] andReturn:dictionary] dictionaryForKey:@"response"];

    BOOL result = [myClass doSomeWork];

    STAssertTrue(result, @"not working right");

    [myClass release];
    [userDefaultsMock verify];
}

My class:

@implementation MyClass

@synthesize userDefaults;
- (id)initWith:(NSUserDefaults *aValue)
{
    if (self = [super init])
    {
        self.userDefaults = aValue;
    }
    return self;
}

- (BOOL)doSomeWork
{
    NSDictionary *response = [userDefaults dictionaryForKey:@"response"];

    if (response != nil)
    {
        // some stuff happens here
        return YES;
    }

    return NO;
}   
@end

Any suggestions?

A: 

Not sure if you figured this out but it's probably to do with using stub with verify. You should use verify with expect.

i.e.

[[[userDefaultsMock expect] andReturn:dictionary] dictionaryForKey:@"response"];
...
[userDefaultsMock verify];

In this instance you use verify to confirm that your method did in fact call the expected method (dictionaryForKey:). You use stub to allow your method to call a given method on a Mock Object but you don't need to verify that it was called.

Ian Kynnersley