Get number rows in UITableView while unit tests- swift?

NinjaDeveloper picture NinjaDeveloper · Jun 2, 2016 · Viewed 8.7k times · Source

I'm writing a test case for UIViewController that has UITableView. I want to ask how can I get number of rows in UITableView

 func testloadingDataIntoUiTableView()
    {      
      var  countRow:Int =  viewController.formListTableView.numberOfRowsInSection   
      XCTAssert(countRow == 4)  
    }

Answer

Luca Angeletti picture Luca Angeletti · Jun 2, 2016

Introduction

Please keep in mind that the data model generates the UI. But you should not query the UI to retrieve your data model (unless we are talking about user input).

Lets look at this example

class Controller:UITableViewController {

    let animals = ["Tiger", "Leopard", "Snow Leopard", "Lion", "Mountain Lion"]
    let places = ["Maveriks", "Yosemite", "El Capitan"];

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 2
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch section {
        case 0: return animals.count
        case 1: return places.count
        default: fatalError()
        }
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCellWithIdentifier("MyCellID") else { fatalError("Who took the MyCellID cell???") }
        switch indexPath.section {
        case 0: cell.textLabel?.text = animals[indexPath.row]
        case 1: cell.textLabel?.text = places[indexPath.row]
        default: fatalError()
        }
        return cell
    }
}

The ugly solution

In this case to get the total number of rows into the table we should query the model (the animals and places properties), so

let controller: Controller = ...
let rows = controller.animals.count + controller.places.count

The nice solution

Or even better we could make the animals and places properties private and add a computed property like this

class Controller:UITableViewController {

    private let animals = ["Tiger", "Leopard", "Snow Leopard", "Lion", "Mountain Lion"]
    private let places = ["Maveriks", "Yosemite", "El Capitan"];

    var totalNumberOfRows: Int { return animals.count + places.count }

    ...

Now you can use this

let controller: Controller = ...
let rows = controller.totalNumberOfRows