Episode #82

TDD View Controllers with Specta and OCMock

16 minutes
Published on August 29, 2013

This video is only available to subscribers. Get access to this video and 584 others.

In this episode I cover test driving a UIViewController using Specta and OCMock. We'll first talk about how to verify that your storyboard is wired up correctly with all outlets & actions and then talk about how to isolate the view controller from other dependencies using mock objects.

Episode Links

Testing Outlets

describe(@"ViewController", ^{
    __block ViewController *_vc;
    beforeEach(^{
        UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
        UINavigationController *nav = [mainStoryboard instantiateInitialViewController];
        _vc = (ViewController *)[nav visibleViewController];

        UIView *view = _vc.view;
        expect(view).toNot.beNil();
    });


    it(@"should be instantiated from the storyboard", ^{
        expect(_vc).toNot.beNil();
        expect(_vc).to.beInstanceOf([ViewController class]);
    });

    it(@"should have an outlet for the username field", ^{
        expect(_vc.usernameTextField).toNot.beNil();
    });

    it(@"should have an outlet for the password field", ^{
        expect(_vc.passwordTextField).toNot.beNil();
    });

    ...
});

Testing Actions

    it(@"should wire up the login button action", ^{
        UIButton *button = _vc.loginButton;
        NSArray *actions = [button actionsForTarget:_vc forControlEvent:UIControlEventTouchUpInside];
        expect(actions[0]).to.equal(@"loginTapped:");
    });

Mocking other dependencies

    describe(@"logging in", ^{
        // vc => login service
        it(@"should verify username & password with the login service", ^{
            //arrange
            id mockLoginService = [OCMockObject mockForClass:[LoginService class]];
            [[mockLoginService expect] verifyUsername:@"user1"
                                             password:@"password1"
                                           completion:[OCMArg any]];

            _vc.loginService = mockLoginService;
            _vc.usernameTextField.text = @"user1";
            _vc.passwordTextField.text = @"password1";


            //act
            [_vc loginTapped:nil];

            // assert
            [mockLoginService verify];
        });
    });