Wednesday, June 25, 2008

XCode unit testing and Bundle Resources

In order to test the code that reads images I needed to set up tests that read images. In order to do this repeatably the best thing seemed to be to add them to the bundle of test application. In XCode this is quite simple - I just dragged in a folder of test images into the right place in my source files and XCode magically knows that these are to be copied - updating the copy files phase of the project.
Having done this the first part of my unit test was to get a url of a PNG in the bundle:

 CFURLRef png1 = ::CFBundleCopyResourceURL(
    CFBundleGetMainBundle(),
    CFSTR("DWCGImageSource_100x100a.png"), NULL, NULL);
 CPTAssert(png1);

This test failed immediately. It failed because URL of the main bundle when running the test is /Developer/Tools. Increasingly my calls to core foundation are lightly wrapped and CFBundleGetMainBundle() is a default parameter to my functions that get thr URLs of things relative to bundles. The solution I found was to add a #define _UNITTEST in the global defines and to write a new function to get the bundle.

 inline CFBundleRef GetMainBundle()
 {
 #if _UNITTEST
  return ::CFBundleGetBundleWithIdentifier(
    CFSTR("com.badbase.cello.unittest"));
 #else
  return CFBundleGetMainBundle();
 #endif
 }
I then use this GetMainBundle in the places where I used CFBundleGetMainBundle.

No comments: