TDD View Controllers with Specta and OCMock

Episode #82 | 16 minutes | published on 08/29/2013
Subscribers Only
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];
        });
    });
blog comments powered by Disqus
Back