簡體   English   中英

在 UITableViewCell XCTest 中測試單元格

[英]Test Cell in a UITableViewCell XCTest

我正在測試視圖控制器所在的 UITableView

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        setup()
    }

    func setup() {
        tableView.dataSource = self
        tableView.delegate = self
        tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "CustomTableViewCell")
    }


    var data = [1,2,3,4,5,6,7]
}

extension ViewController : UITableViewDelegate {

}

extension ViewController : UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell", for: indexPath)
        cell.textLabel?.text = data[indexPath.row].description
        return cell
    }    
}

與測試

func testViewCell() {
    guard let controller = controller else {
        return XCTFail("Could not instantiate ViewController")
    }

    let tableCell = Bundle(for: CustomTableViewCell.self).loadNibNamed("CustomTableViewCell", owner: nil)?.first as! CustomTableViewCell
    tableCell.textLabel?.text = "2"

    controller.loadViewIfNeeded()
    let actualCell = controller.tableView!.cellForRow(at: IndexPath(row: 0, section: 0) )

    XCTAssertEqual(actualCell, tableCell)}

但是我得到的單元格為零。

這是令人驚訝的,因為視圖控制器中的斷點表明正在分配單元格,因此行中有錯誤

let actualCell = controller.tableView!.cellForRow(at: IndexPath(row: 0, section: 0) )

那么如何測試這個單元格的內容呢?

問題 1:如果您在筆尖中定義單元格,則需要注冊該筆尖(而不是類型)。

tableView.register(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "CustomTableViewCell")

問題二:好像直接調用controller.tableView!.cellForRow(at:)可以返回nil 但這不是 UIKit 調用表格視圖的方式。 相反,通過其數據源調用它。 讓我們做同樣的測試:

let actualCell = controller.tableView.dataSource?.tableView(controller.tableView, cellForRowAt: IndexPath(row: 0, section: 0))

現在返回一個單元格,並且斷言失敗,說明 CustomTableViewCell 的兩個實例不相等。

獎勵:如果您想將數據源移動到一個單獨的類中,您可以在不更改測試的情況下這樣做。 測試不知道也不關心誰實現了數據源。

問題 3:更改測試以設置"1"作為預期單元格的文本標簽仍然沒有通過。 這可能是因為每個單元格都有自己的layer 因此,與其設置預期的單元格,不如將實際單元格轉換為 CustomTableViewCell。 然后你可以檢查它的屬性。

guard let cell = actualCell as? CustomTableViewCell else {
     XCTFail("Expected \(CustomTableViewCell.self), but was \(actualCell)")
     return
}
XCTAssertEqual(cell.textLabel?.text, "1")

改進:遍歷表視圖的數據源,並將表視圖作為第一個參數傳遞給它很尷尬。 通過定義獨立的輔助函數,我們可以更容易地閱讀和編寫表格視圖測試。

func cellForRow(in tableView: UITableView, row: Int, section: Int = 0) -> UITableViewCell? {
    return tableView.dataSource?.tableView(tableView, cellForRowAt: IndexPath(row: row, section: section))
}

使用這個助手,我們可以簡單地寫:

let actualCell = cellForRow(in: controller.tableView row: 0)

第 1 步:轉到故事板中視圖控制器的 Identity Inspector 並為其指定故事板 ID。 例如:“vcIdentifier”

第 2 步:您已經在單元測試中獲得了故事板的實例

第 3 步:通過第 2 步中的故事板實例實例化您的視圖控制器

第 4 步:從視圖控制器訪問您的表視圖,並將其傳遞給測試中的“cellForRowAt”方法。 請參閱下面的示例代碼:

let storyboard = UIStoryboard(name: "Main", bundle:nil)
let newsViewController: UITableViewController = storyboard.instantiateViewController(identifier: "vcIdentifier")
return newsViewController.tableView // Use this tableview to call 'cellforRow'

第 5 步:刪除在測試代碼中添加的任何 tableview.register() 方法。 如果注冊cell方法,所有的outlet都會丟失。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM