There has been a lot of confusion about unit testing view controllers. I’ve had people tell me that one should only unit test model objects and not view controllers. I’ve even been told that it isn’t possible to unit test view controllers. Don’t you believe it.
Let me clarify a few things about unit testing view controllers:
- View controllers typically contain most of the developer written code for an iOS project. Choosing not to test view controllers is essentially making the decision to not test most of the code you write.
- ViewController unit tests should test the methods of the view controller. This means that each test method in the ViewControllerTests.m file should be testing one of the methods of the view controller.
So for example, I would expect there to be a test method named “testViewDidLoad” that tests whether viewDidLoad works as intended. This means verifying that the code you put in viewDidLoad does what you expect the it to do.
- Unit testing a view controller nearly always means writing the view controller methods differently. In untested view controllers, viewDidLoad usually has a LOT of code thrown into it. This works, but is not very testable. Instead, viewDidLoad should call helper methods. Each of the helper methods should do just one thing (Refer to SOLID object oriented principles). Then the unit tests can test those helper methods to verify that the one thing is done correctly. It also means that the test for viewDidLoad probably just verifies that those helper methods are actually called. This can be done using a partial mock object. Each helper method should also be named in a way that makes it clear exactly what that one this is.
- The view controller unit tests should not be testing anything besides the view controller. If the view controller calls another object, then the view controller tests should verify that the other object is called (for example, using mocks), but should not test what the other object does. The unit tests for that other object should test that.
- And as with all unit tests, we should not try to test things that are done by the runtime or iOS libraries.
Unit testing view controllers appears daunting at first, but with a little experimentation and practice, it becomes fairly easy.