4

I would like to unit test if the custom cell is registered with the tableView.

-(void)viewDidLoad
{
    [super viewDidLoad];
    UINib *nib = [UINib nibWithNibName:@"FTStatsCellView" bundle:nil];
    [[self tableView] registerNib:nib forCellReuseIdentifier:@"FTStatsCellView"];
}

Unit test:

-(void)testIfCustomCellsAreRegisteredToTable
{
    [viewController viewDidLoad];
    FTStatsCellView *cell = [[viewController tableView] dequeueReusableCellWithIdentifier:@"FTStatsCellView"];
    XCTAssertNotNil(cell, @"Custom cell FTStatsCellView is not registered with the table.");
}

The test fails with the message:

[FTStatsViewControllerTests testIfCustomCellsAreRegisteredToTable] failed: Could not load NIB in bundle: 'NSBundle (loaded)' with name 'FTStatsCellView'

Any advice? thanks

Update

If I click on the project and change the test target's target from None to the application, then it works.

enter image description here

But this has the side effect that the app runs in the simulator each time I want to run a unit test.

enter image description here

Any advice?

Houman
  • 64,245
  • 87
  • 278
  • 460
  • 1
    Have you included the nib into your test target? – Wain Jan 05 '14 at 17:41
  • It seems I have a similar issue as here: http://stackoverflow.com/questions/1879247/why-cant-code-inside-unit-tests-find-bundle-resources But don't know how to combine path with `nibWithNibName`. – Houman Jan 05 '14 at 20:57
  • Btw the xib file is already checked for the test target membership. It is included the the test target's `copy bundle resources`. I am stuck... – Houman Jan 05 '14 at 21:00
  • But the app _has_ to run in the simulator if you want to perform this kind of test, because it is the kind of test that requires the app to be running. This is a test that is _about_ what the app does when it runs. What's so wrong with that? Don't worry, be happy. – matt Jan 05 '14 at 21:59
  • _Don't_ include production nibs in test targets. The tests need to be injected into a running app, as I explain in my updated answer. …I recommend you update the question title. – Jon Reid Jan 05 '14 at 22:14

1 Answers1

1

Setting the Target specifies both BUNDLE_LOADER and TEST_HOST for the test target. This is necessary for the following sequence when running unit tests:

  1. Xcode launches your app in the simulator (or on device, but I never run unit tests on device)
  2. Xcode injects the test target into the running app
  3. Xcode invokes all tests
  4. Xcode quits your app

All this is necessary for unit tests that operate on top of Cocoa Touch — in particular, anything involving a view controller loading its view hierarchy.

Jon Reid
  • 20,545
  • 2
  • 64
  • 95
  • Thanks Jon for the reply. Unfortunately the trick didn't really help. Its the same problem as before. However I made a discovery, if you could read the update to the question please. – Houman Jan 05 '14 at 21:55
  • I would put this even more strongly: _never_ call `viewDidLoad`. It is not for you to call a method used by the runtime to report a stage in the lifetime of an object. It is up to the runtime to call `viewDidLoad`, because the view _did_ load. – matt Jan 05 '14 at 21:57
  • Thanks @matt, but even `[viewController view]` doesn't solve the actual problem. Please see updated question. – Houman Jan 05 '14 at 21:59