Search code examples
iosobjective-cunit-testingios6gh-unit

Unit testing IBOutlet's properties


I use GHUnit. I want to test IBOutlet's properties such as isHidden, delegate, etc.

I tried below code to test if myView is hidden :

- (void)testViewDidLoad
{
    // Call view on viewcontroller which will load the view if not loaded
    [testClass view];

    // Tests
    testClass.myView.hidden = YES;

    if (testClass.myView.isHidden) {
        GHTestLog(@"Hidden");
    }
    else {
        GHTestLog(@"Not Hidden");
    }
}

This always logs Not Hidden, whereas just before logging I set it hidden = YES.

Why is this?

To test delegate property of an IBOutlet I tried below line :

GHAssertNotNil(testClass.textField.delegate, @"delegate is nil.");

It fails with Reason : ((testClass.textField.delegate) != nil) should be FALSE.

What is wrong?

EDIT : Tried below code which does not work.

[testClass view];

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard"
                                         bundle:[NSBundle bundleForClass:[self class]]];
GHAssertNotNil(storyboard, nil);

// Tests
GHAssertTrue(testClass.myView.isHidden, nil);  // This fails

Solution

  • When testing your views contained in a UIStoryboard, make sure that you've added your storyboard file to the test target.

    I'd also suggest that you have a test that validates that your storyboard was successfully initialized like this:

    - (void)testStoryboardShouldBeInitialized
    {
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"NameOfStoryboard" bundle:[NSBundle bundleForClass:[self class]]];
        STAssertNotNil(storyboard, nil);
    }
    

    Edit

    You first have to instantiate your view controller you'd like to test from your storyboard and then you can test your outlet:

    UIViewController *controller = [storyboard instantiateViewControllerWithIdentifier:@"ViewControllerIdentifier"];
    [controller view];
    GHAssertTrue(controller.myView.isHidden, nil);
    

    I'd also recommend to test (in a separate method) that your view controller is successfully instantiated. I'd also move the controller initialization into your setUp method - if necessary.