objective-cunit-testingocmock

How to stub a call to a method with a reference argument?


Consider this:

+(NSDictionary *)getDictionaryFromData:(id)data {
    @synchronized(self) {
        NSError *error = nil;
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
        if (error) {
            DLog(@"SERIALIZATION FAILED: %@", error.localizedDescription);
            return nil;
        }

        DLog(@"SUCCESS: %@", dict);
        return dict;
    }
}

How do I mock getDictionaryFromData to get coverage if error is not nil? Is it possible or do I have to actually mock the JSONObjectWithData method?


Solution

  • For this answer I'm assuming you don't actually want to mock the getDictionaryFromData: method. I assume you want to test its implementation, how it deal with an error case.

    You can stub that JSONObjectWithData:options:error: method and return an error in the pass by ref argument; somehow like this:

    id serializerMock = [OCMock mockForClass:[NSJSONSerialization class]];
    NSError *theError = /* create an error */
    [[[serializerMock stub] andReturn:nil] JSONObjectWithData:data 
        options:NSJSONReadingAllowFragments error:[OCMArg setTo:theError]];
    

    The trick here is obviously the setTo: method.