Wis*_*uns 2 tdd ios xctest swift
我正在测试视图控制器所在的 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
}
}
Run Code Online (Sandbox Code Playgroud)
与测试
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)}
Run Code Online (Sandbox Code Playgroud)
但是我得到的单元格为零。
这是令人惊讶的,因为视图控制器中的断点表明正在分配单元格,因此该行有问题
let actualCell = controller.tableView!.cellForRow(at: IndexPath(row: 0, section: 0) )
Run Code Online (Sandbox Code Playgroud)
那么我该如何测试这个单元格的内容呢?
问题 1: 如果您在笔尖中定义单元格,则需要注册该笔尖(而不是类型)。
tableView.register(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "CustomTableViewCell")
Run Code Online (Sandbox Code Playgroud)
问题2:
貌似直接调用controller.tableView!.cellForRow(at:)就可以返回nil。但这不是 UIKit 调用表视图的方式。相反,通过其数据源调用它。让我们进行同样的测试:
let actualCell = controller.tableView.dataSource?.tableView(controller.tableView, cellForRowAt: IndexPath(row: 0, section: 0))
Run Code Online (Sandbox Code Playgroud)
现在返回一个单元格,并且断言失败,表明 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")
Run Code Online (Sandbox Code Playgroud)
改进: 遍历表视图的数据源并将表视图作为第一个参数传递给它是很尴尬的。我们可以通过定义独立的辅助函数来使读取和编写表视图测试变得更容易。
func cellForRow(in tableView: UITableView, row: Int, section: Int = 0) -> UITableViewCell? {
return tableView.dataSource?.tableView(tableView, cellForRowAt: IndexPath(row: row, section: section))
}
Run Code Online (Sandbox Code Playgroud)
使用这个助手,我们可以简单地编写:
let actualCell = cellForRow(in: controller.tableView row: 0)
Run Code Online (Sandbox Code Playgroud)