0
votes

I want to test object mapping (RKObjectMapping) of the model of my project. I created .json file in the project. It contains:

{"access_token" : "this_is_a_token_123"}

When it has been mapped after request it looks like this in mappingResult object:

2013-12-02 07:15:00.315 Capture The Flag[30320:70b] mapp = <RKMappingResult: 0x8e89ba0, results= {
"<null>" = "<CTFAPIOBJToken: 0x8e8b690>";
}>

class interface:

@interface CTFAPIOBJToken : NSObject
@property NSString *value;

+ (RKResponseDescriptor *)responseDescriptor;
+ (RKObjectMapping *)objectMapping;

@end

class implementation:

@implementation CTFAPIOBJToken
+ (RKObjectMapping *)objectMapping {
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[CTFAPIOBJToken class]];
[mapping addAttributeMappingsFromDictionary:@{@"access_token" : @"value"}];
return mapping;
}

And test:

- (void)setUp {
[super setUp];
NSBundle *bundle = [NSBundle bundleWithIdentifier:[[NSBundle mainBundle].bundleIdentifier stringByAppendingString:@"Tests"]];
[RKTestFixture setFixtureBundle:bundle];
}


- (RKMappingTest *)mappingTest {
id parsedJSON = [RKTestFixture parsedObjectWithContentsOfFixture:@"token-response.json"];
RKMappingTest *test = [RKMappingTest testForMapping:[CTFAPIOBJToken objectMapping] sourceObject:parsedJSON destinationObject:nil];
return test;
}

- (void)testMapping_AccessToken {
RKMappingTest *test = [self mappingTest];
RKPropertyMappingTestExpectation *expectation =
[RKPropertyMappingTestExpectation expectationWithSourceKeyPath:@"access_token" destinationKeyPath:@"value"];
[test addExpectation:expectation];
NSError *error = nil;
BOOL result = [test evaluate];
NSLog(@"error = %@", error);

XCTAssertTrue(result, @"value should be defined");
}

And now, when I make request to the sever I successfuly receive object of class under the test and in property value is value from access_token = this_is_a_token_123 received from server in response. When I want to test it I've got following error:

Test Case '-[CTFAPIOBJTokenTests testMapping_AccessToken]' started.
<unknown>:0: error: -[CTFAPIOBJTokenTests testMapping_AccessToken] : 0x8e4e680: failed with error: (null)
RKMappingTest Expectations: (
"map 'access_token' to 'value'"
)
Events: (
) during mapping from <CFBasicHash 0x8e4a360 [0x225dec8]>{type = immutable dict, count = 1,
entries =>
1 : <CFString 0x8e56fd0 [0x225dec8]>{contents = "access_token"} = <CFString 0x8e56ff0 [0x225dec8]>{contents = "this_is_a_token_123"}
}
 to (null) with mapping <RKObjectMapping:0x8e4a390 objectClass=CTFAPIOBJToken propertyMappings=(
"<RKAttributeMapping: 0x8e438d0 access_token => value>"
)>
(
0   CoreFoundation                      0x021125e4 __exceptionPreprocess + 180
1   libobjc.A.dylib                     0x01e958b6 objc_exception_throw + 44
2   CoreFoundation                      0x021123bb +[NSException raise:format:] + 139
3   Capture The FlagTests               0x0a8e8a9b -[RKMappingTest performMapping] + 1067
4   Capture The FlagTests               0x0a8e93a3 -[RKMappingTest evaluate] + 99
5   Capture The FlagTests               0x0a80e612 -[CTFAPIOBJTokenTests testMapping_AccessToken] + 194
6   CoreFoundation                      0x02106d1d __invoking___ + 29
7   CoreFoundation                      0x02106c2a -[NSInvocation invoke] + 362
8   XCTest                              0x201032bf -[XCTestCase invokeTest] + 212
9   XCTest                              0x2010338d -[XCTestCase performTest:] + 111
10  XCTest                              0x2010417c -[XCTest run] + 82
11  XCTest                              0x20102a44 -[XCTestSuite performTest:] + 139
12  XCTest                              0x2010417c -[XCTest run] + 82
13  XCTest                              0x20102a44 -[XCTestSuite performTest:] + 139
14  XCTest                              0x2010417c -[XCTest run] + 82
15  XCTest                              0x20102a44 -[XCTestSuite performTest:] + 139
16  XCTest                              0x2010417c -[XCTest run] + 82
17  XCTest                              0x20105aa1 +[XCTestProbe runTests:] + 183
18  Foundation                          0x01acc12c __NSFireDelayedPerform + 372
19  CoreFoundation                      0x020d0bd6 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
20  CoreFoundation                      0x020d05bd __CFRunLoopDoTimer + 1181
21  CoreFoundation                      0x020b8628 __CFRunLoopRun + 1816
22  CoreFoundation                      0x020b7ac3 CFRunLoopRunSpecific + 467
23  CoreFoundation                      0x020b78db CFRunLoopRunInMode + 123
24  GraphicsServices                    0x03ad89e2 GSEventRunModal + 192
25  GraphicsServices                    0x03ad8809 GSEventRun + 104
26  UIKit                               0x00c03d3b UIApplicationMain + 1225
27  Capture The Flag                    0x0000705d main + 141
28  libdyld.dylib                       0x0275070d start + 1
)
Test Case '-[CTFAPIOBJTokenTests testMapping_AccessToken]' failed (0.028 seconds).

What is wrong with this test?

Edit.

Now I think that this object mapping is incorrect. It should be something like this:

{"tokenobject": {"access_token": "this is a token"}}

In my case above it looks like this is a token string has been mapped to the property value of CTFAPIOBJToken object but it's look strange because this whole object in mapping result is under the key: "null" which is NSNull or something like that right? It's strange and it also strange to test. IMO it should looks like following in mappingResult.array object in success block:

{
    CTFAPIOBJToken <address>
}

One way to do this without mapping is to use AFNetworking which is used in RestKit also. RKObjectManager has property client or something like that which is type of AFHTTPClient.

1
So what is the problem? An exception? Or this is fixed and the issue is understanding the mapping result? Have you confirmed the JSON? - Wain
I don't understand why my mapping is wrong for JSON presented on top of the topic. and why mappingResult has dictionary with key "null" for object CTFAPIOBJToken. - Tomasz Szulc

1 Answers

1
votes

The mapping describes what to take out of the JSON and what to do with it. It is used in conjunction with the response descriptor to determine where it should be allied. If either is wrong you will have mapping problems as either RestKit will be looking in the wrong place or looking for the wrong data.

In the response mapping the result is against a key of NSNull because you have a nil keypath in the response descriptor. This means that a restKit has no key information to associate the result data with and it need to use some generic key.