Reputation: 58
I've been working on my unit tests for iOS programming, and I've run into a little problem when trying to validate my main class by mocking it's child classes using OCMock and then seeing if the main class adds the child controllers (mockObjects[uiviewContoller]) and then verifying that an object calls a method on each of the child controllers.
The problem is I keep getting a "test failed 'adding a root view controller OCMockObject[UiViewController] as a child of view controller'"
every other time i run the test.
- (void)setUp
{
[super setUp];
testMain = [[UIViewController alloc] init];
}
- (void)tearDown
{
for (UIViewController *testCon in testMain.childViewControllers) {
[testCon removeFromParentViewController];
}
testMain = nil;
[super tearDown];
}
test:
- (void) testDayNightTriggerTriggersAllSubviews{
id mockTopController = [OCMockObject niceMockForClass:[UIViewController class]];
id mockBottomController = [OCMockObject niceMockForClass:[UIViewController class]];
id mockMainScreen = [OCMockObject niceMockForClass:[UIViewController class]];
[[mockTopController expect] dayNightTrigger];
[[mockBottomController expect] dayNightTrigger];
[[mockMainScreen expect] dayNightTrigger];
//trigger
[testMain dayNightTrigger:mockTopController bottom:mockBottomController main:mockMainScreen];
[mockBottomController verify];
[mockTopController verify];
[mockMainScreen verify];
}
Method to verify:
//overload
- (void) dayNightTrigger:(UIViewController *) top bottom:(UIViewController *)bottom main:(UIViewController *)main{
self.bottomMenu = bottom;
self.topMenu = top;
self.mainScreen = main;
[self dayNightTrigger];
}
- (void) dayNightTrigger{
[self.app dayNightTrigger];
[self.bottomMenu dayNightTrigger];
[self.topMenu dayNightTrigger];
[self.mainScreen dayNightTrigger];
}
I was wondering if there is anything wrong with my setup/teardown? or I'm doing something wrong with the OCMock framework, but really as to why I keep getting this error.
Upvotes: 0
Views: 1360
Reputation: 46
I've run into the same issue. I'm guessing that your properties bottomMenu, topMenu, and mainScreen set bottom, top, and main as child view controllers of the other view controller.
Unfortunately, addChildViewController: looks at some value in the UIViewController* structure. Since it's a direct memory access and not a method call, the OCMockObject can't intercept it. As a result, the mock object is (sometimes) treated as being a root view.
The way I found around it was to override addChildViewController: on the object I was testing in the test file and have it do nothing:
@implementation MyViewController (overwriteForTesting)
- (void)addChildViewController:(UIViewController *)childController {
}
@end
This means that it won't add the view controller to its list of children though.
Upvotes: 3