objective-ccocoac-preprocessorocunit

Unit testing in presence of C API functions


My application uses third-party C APIs for some tasks. I was wondering how to unit test the classes that make calls to the API, since the unit testing environment is impractical to set up so that it works.

An example. One of my classes might have a method like this:

- (id) doSomeStuff
{
    // my code
    // ...
    thirdPartyDoStuffFunction(17, 4);
    // etc...
}

The corresponding unit test:

- (void) testDoSomeStuff
{
    MyClass *x = [[MyClass alloc] init];
    id result = [x doSomeStuff];

    STAssertNotNil(result, @"Result mustn't be nil");
}

Let's say that for reasons beyond my control, calling thirdPartyDoStuffFunction while running the unit testing target will crash the test. For this reason, and because I want to make sure the function has been called with the right arguments, I would like to mock it.

This is what I have tried so far:

Update: Both of the above approaches work for me now. The reason they didn't seems to be that the implementation files (.m) of the classes under test had not been added to the unit test target. Once I added them, the macros are being executed as expected, i.e. they override the third-party API.

I still wonder why there were no compiler/linker errors and the unit tests actually ran while some of the implementation wasn't present in their target, but the important thing is that it works now.


Solution

  • You should create a header file TestRedirect.h with the following contents:

    #ifdef UNIT_TESTING
    
    #define thirdPartyDoStuffFunction MyTest_thirdPartyDoStuffFunction
    ..........
    
    #endif
    

    You include this file into all files with your classes that you want to test. After that you create 2 different builds:

    Your test functions should be defined simply as MyTest_thirdPartyDoStuffFunction and they should be included into the linking only in the test configuration.