People assume you can’t write unit tests for user interface code. That just ain’t so. I’ve already shown you how to do UIViewController TDD. Can we do the same for UIAlertView and UIActionSheet? Sure!
This time instead of a screencast, I’ve put my code on GitHub, because you’ll want to incorporate some classes into your tests. Go to my iOSAlertViewActionSheetUnitTesting repository.
The basic trick to writing unit tests of UI code is to recognize that we don’t manage the UI ourselves. Cocoa Touch takes care of that. All we have to do is make sure we’re setting things up correctly for Cocoa Touch, and trust it to do its work. …Do you see the distinction? We don’t need to test Apple’s code, just our code. (This also keeps our tests fast.)
We do need to introduce a seam — that is, a boundary that will allow us to substitute real code with test-specific code. The real code we want to replace is directly invoking UIAlertView or UIActionSheet. Normally, you’d show an alert with code like this:
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Title" message:@"Message" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil]; [alertView show];
Instead of directly allocating a UIAlertView, what if we allow tests to say, “Don’t make a UIAlertView. Instead, make this mock object. It will record everything I do to it, so I can check all initializer arguments, and make sure
show was messaged.”
That’s where JMRMockAlertView and JMRMockActionSheet come in. The repository has an example project showing how to inject them, and how to use the corresponding objects JMRMockAlertViewVerifier and JMRMockActionSheetVerifier to query what happened.
For the sample tests, I put all the assertions together so you can see them all grouped together. But in practice, I break things into separate tests for:
Once you’ve established the delegate, then you can write additional tests that directly invoke the delegate methods you want, simulating different button taps.
Oh, and don’t just copy my end result. Use the “TDD waltz” to build it up gradually, one test at a time. You can see a good order by reading my tests top-down.
Do you have any questions? Leave a comment below.
Jon is a consultant on Clean Code for iOS, focusing on Test Driven Development, unit testing, refactoring, and design. He's been practicing TDD since 2001. You can learn more about his background, or see what services he can bring to your organization.
Please log in again. The login page will open in a new window. After logging in you can close it and return to this page.