Take the 2-minute tour ×

I have an OCUnit Test class: PatientTestViewControllerTests. Below is the interface:

@interface PatientTestViewControllerTests : SenTestCase

@property (nonatomic, strong) PatientTestViewController *testController;


and setUp:

- (void) setUp
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Testing" bundle:nil];
    self.testController = [storyboard instantiateInitialViewController];

The 'Testing' storyboard is the only storyboard in my app, and is set as the app's main storyboard. The PatientTestViewController is set as the storyboard's only view controller.

I have one test in my test class:

- (void) testInitialTestingStoryboardViewIsPatientTest
    STAssertTrue([self.testController isMemberOfClass:[PatientTestViewController class]], @"Instead of the %@, we have %@",[PatientTestViewController class], [self.testController class]);

This test fails with the following log message:

error: -[PatientTestViewControllerTests testInitialTestingStoryboardViewIsPatientTest] : "[self.testController isMemberOfClass:[PatientTestViewController class]]" should be true. Instead of the PatientTestViewController, we have PatientTestViewController

How can this be? Since

[self.testController isMemberOfClass:[PatientTestViewController class]]

is apparently false, how can the test log say that both

[self.testController class] and [PatientTestViewController class]

look the same?

Additional Info:

  • using [self.testController isKindOfClass:[PatientTestViewController class]] in the test also fails
  • using [self.testController class] == [PatientTestViewController class] fails also.

  • using [self.testController isKindOfClass:[UIViewController class]] PASSES.

  • using [self.testController isMemberOfClass:[UIViewController class]] FAILS.
share|improve this question
Out of curiousity, what does NSLog(@"Expected address: %p, actual: %p",[PatientTestViewController class], [self.testController class]); look like? –  Josh Caswell Jul 26 '12 at 18:35
@JoshCaswell Aha. Interesting question! And an interesting answer. "Expected address: 0x679fa48, actual: 0x59bc" So... what does that mean? Obviously they're different memory addresses... but what does isMemberOfClass test against? Is it strict object equality, like '=='? –  churowa Jul 26 '12 at 18:39
@JoshCaswell Interestingly enough, if I instantiate the testController object in setUp using a standard alloc/init, the test passes with no problems, and the two addresses are identical. So why does [UIStoryboard instantiateInitialViewController] return something different.. and how is it different? –  churowa Jul 26 '12 at 18:45
I'm not sure how isMemberOfClass: checks equality internally. I kind of suspect UIStoryboard has created a dummy stand-in class for some reason. Possibly some sort of laziness. How about this: what happens if you send a message to the testController, then do isMemberOfClass:, isKindOfClass:, and print the address? –  Josh Caswell Jul 26 '12 at 18:50
I'm thinking that you may be on to something here. Sending a message to the testController didn't change anything (still the same discrepancy in addresses). However, I created a new project to replicate the problem, and I can't replicate it. The only real difference between the two projects is that I was fiddling around with the Storyboards in my original. I must have done... something. –  churowa Jul 26 '12 at 19:04

2 Answers 2

up vote 9 down vote accepted

The problem is likely that your view controller's .m file is included in both targets, the app and the test bundle. ocunit (and derivatives like Kiwi) uses a test harness that makes the classes included in the app available to tests without having to explicitly include their implementation.

Including both has given you two copies of the same class, which is why they have the same description but different memory addresses.

share|improve this answer
Dumbfounded. That's exactly it. Removed the .m file from the Test target, and blammo. Everything passes. I'm used to GHUnit, where you have to include the .m file in both targets. –  churowa Jul 26 '12 at 20:10
Thanks - you've just resolved HOURS of head-scratching and nasty creating-NSStrings-from-class-names workarounds! –  TimD Dec 12 '12 at 15:25
Save my day!!! Thank you point this out. I add my model file in my test project, but it's don't needed. –  Jiejing Zhang Apr 22 at 16:54
To tack on to this answer, after you've removed the source files from the test target, you may need to set up the symbols to unhide themselves. –  Richard Shin May 2 at 17:07

You generally want isKindOfClass: and not isMemberOfClass:. The difference is that isKindOfClass: will return YES if the receiver is a member of a subclass of the class in question, whereas isMemberOfClass: will return NO in the same case.

You could also directly compare the classes using [self.testController class] == [PatientTestViewController class].

share|improve this answer
Thanks for the reply. I wanted the test to be specific, that's why I used isMemberOfClass. The initial view of the storyboard should be PatientTestViewController exactly, not a subclass. However, I did actually try isKindOfClass as well, just to be sure. No dice. I like the idea of the '==' test, but it doesn't work either. :( I'll put some additional info in the question with what else I've tried. –  churowa Jul 26 '12 at 18:32

Your Answer


