1

I'm attempting to follow along with the RestKit unit test guide ( https://github.com/RestKit/RestKit/wiki/Unit-Testing-with-RestKit ) except that my project is a static library instead of an app.

Here is the test I've written:

- (void)testMappingOfDate
{
    id parsedJSON = [RKTestFixture parsedObjectWithContentsOfFixture:@"plan.json"];
    RKMappingTest *test = [RKMappingTest testForMapping:[self planMapping] object:parsedJSON];
    [test expectMappingFromKeyPath:@"plan.date" toKeyPath:@"date"];
    STAssertNoThrow([test verify], nil);
}

When I attempt to run the test I receive this error on the first line of the test:

error: testMappingOfDate (api_clientTests) failed: -[NSBundle parsedObjectWithContentsOfResource:withExtension:]: unrecognized selector sent to instance 0x1765c40

It seems like its not finding the NSBundle category defined by RestKit, but my test target header search path is set to "$(BUILT_PRODUCTS_DIR)/../../Headers" and I've verified this path includes NSBundle+RKAdditions.h which contains the supposed "unrecognized selector".

Is there something I'm missing here?

mark
  • 1,398
  • 13
  • 30

2 Answers2

2

You are trying to include a category within your binary that comes from a library. To get that accomplished you will need to add the following to your (Unit-Test-Target's) build settings.

Other Linker Flags: -ObjC

enter image description here

From Apple's QA:

Objective-C does not define linker symbols for each function (or method, in Objective-C) - instead, linker symbols are only generated for each class. If you extend a pre-existing class with categories, the linker does not know to associate the object code of the core class implementation and the category implementation. This prevents objects created in the resulting application from responding to a selector that is defined in the category.

Solution:

To resolve this issue, the static library should pass the -ObjC option to the linker. This flag causes the linker to load every object file in the library that defines an Objective-C class or category. While this option will typically result in a larger executable (due to additional object code loaded into the application), it will allow the successful creation of effective Objective-C static libraries that contain categories on existing classes.

Till
  • 27,559
  • 13
  • 88
  • 122
  • that link does not exist (I am on a free developers account but I don't think that effects the lookup) Google seems to give http://developer.apple.com/library/mac/#qa/qa1490/_index.html – mmmmmm Jul 22 '12 at 20:38
  • This does appear to change the issue, now I get a bunch of errors like : `Undefined symbols for architecture i386: "_CFHTTPMessageAddAuthentication", referenced from: -[RKRequest addHeadersToRequest] in libRestKit.a(RKRequest.o) -[RKRequest addHeadersToRequest] in libopentripplanner-api-client.a(RKRequest.o)` – mark Jul 22 '12 at 20:40
  • You will have to link a bunch of other libraries as well - seems you need to check the documentation of that library you are trying to use. Look out for "frameworks to link against". – Till Jul 22 '12 at 20:45
  • That did it. Apparently I needed to include all the required frameworks in the test bundle as well as the static library. This doesn't appear to be the case when testing an app bundle. When testing an app bundle you only need to include the frameworks in the app bundle and then include the app in the "Bundle Loader" of your test bundle. I don't believe this is possible with a static library. – mark Jul 22 '12 at 20:52
1

The error means that the "unrecognized selector" issue is at runtime. The compiler and NSBundle+RKAdditions.h do not give this error they would at compile timr.

The issue is that the code that has @implementation NSBundle(RKAdditions) is not linked into your app. So you need to add this to your build

mmmmmm
  • 32,227
  • 27
  • 88
  • 117
  • I've added `libReskKit.a` to my test's "Link Binary With Libraries" and I still receive the same error. – mark Jul 22 '12 at 20:22
  • @mark - do you mean to building your static lib or to the unit test run? – mmmmmm Jul 22 '12 at 20:24
  • I now have the `libReskKit.a` in the "Link Binary With Libraries" section of both my static library and my unit test bundle. – mark Jul 22 '12 at 20:25