Unit Testing — UITableView
The most common way to show data to users is using some kind of endless tables like Instagram’s feed, Facebook’s timeline, WhatsApp’s messages and others.
As an iOS Developer, you have some tools to achieve this. You can use a UITableView
, a UICollectionView
, IGListKit
and more. All these tools have things in common, they all use delegate/datasource pattern and have a custom view to show data.
In this post I’ll, show how we can test delegates, datasource and views for our collections using a UITableView
.
Datasource
First of all, let’s create a new file and implement some methods from UITableViewDataSource
. In this example, we are going to use the default UITableViewCell
as our cells and String
as our model but fell free to use whatever cell and model you want.
Our cells will have different titles based on our [String]?
data.
After that, let’s write some tests. Before each test, we are going to create a [String]
to populate our table, create a MyDelegateDatasource
object, register UITableViewCell
to our table and set its delegate and datasource.
We have two tests at the moment:
- Number of rows
- Number of sections
Our rows count should be 5 and should have 1 section. The cellForRow
method is going to be tested later.
Delegate
Our delegate is a little different, to test it we need to mock it and an easy way to do that is to create a protocol.
Every time our user selects a cell we call this protocol. So now we can update MyDelegateDatasource
to have a MyDelegateDatasourceProtocol
object and call it every time the UITableViewDelegate
calls didSelectRow
. Don’t forget to implement UITableViewDelegate
didSelectRow
method.
To test this delegate we need to create an object that implements this protocol, in other words, we need to mock it. We are going to use this object to check if our delegate is being called when UITableViewDelegate
calls didSelectRow
. This mock is simple it just needs to change a boolean value when the didSelectCell
method is called and save the received parameter.
Let’s update our test file creating an MyDelegateDatasourceMock
object and setting the delegate property on MyDelegateDatasource
.
Our delegate test is checking if the didSelectCell
property is false
before we call tableView(tableView, didSelectRowAt: indexPath)
and if it changed to true
after. Also, we are verifying if the data received is the expected.
View
The cellForRow
method is not covered by our test. To check if our UITableViewCell
is behaving as expected we used Nimble+Snapshot. Let’s add some tests to check them.
Implementing a delegate and datasource in its own file helps a lot when testing and make them easier to write and testing them is also very important as part of our project.
This is a part-4 of a series of posts that show how to test some stuff on iOS.
- Part-1 — UIViews with Nimble+Snapshots
- Part-2 — Unit Testing — JSON’s parse
- Part-3 — Unit Testing — Network request
Ps: If you like this post, share it on twitter, recommend it on medium, or both =). This really helps me to reach more people. Thanks a lot.