Ios CellForRowatineXpath单元测试崩溃
我有一个简单的带有一些行的tableview。每一行都是一个带有xib文件的自定义单元格。我已经实现了委托和数据源,当我运行应用程序时,它工作正常。这就是我实现它的方式Ios CellForRowatineXpath单元测试崩溃,ios,swift,uitableview,unit-testing,Ios,Swift,Uitableview,Unit Testing,我有一个简单的带有一些行的tableview。每一行都是一个带有xib文件的自定义单元格。我已经实现了委托和数据源,当我运行应用程序时,它工作正常。这就是我实现它的方式 class P: UITableViewController { override func viewDidLoad() { super.viewDidLoad() registerCell() } func registerCell() { self.t
class P: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
registerCell()
}
func registerCell() {
self.tableView.register(UINib(nibName: "PCell", bundle: nil), forCellReuseIdentifier: "cell")
}
#number of rows implemented here
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! PCell
cell.titleLabel.text = "Great"
return cell
}
}
这段代码运行良好
问题是,当我尝试对tableView进行单元测试时,我遇到了一个问题。这就是我进行单元测试的方式
class MockPController: PController {
}
class PControllerTests: XCTestCase {
let mpc = MockPController()
//THIS IS WORKING
func testNumberOfSections() {
mpc.viewDidLoad()
XCTAssertEqual(mpc.numberOfSections(in: mpc.tableView), 5)
}
func testTitleForPCells() {
mpc.viewDidLoad()
var cell = mpc.tableView(mpc.tableView, cellForRowAt: IndexPath(row: 0, section: 1)) as! PCell
//THE APP CRASHES AT THE CELLFORROWATINDEXPATH FUNCTION IN ACTUAL CODE - HERE "let cell = self.tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! PCell"
//APP CRASHES HERE SAYING "Could not cast value of type 'Project.PCell' to 'ProjectTests.PCell'
}
}
在遇到这个应用程序崩溃时,我在MockPController中为registerCell()添加了一个覆盖函数,因此新的MockPController变为
class MockPController: PController {
override func registerCell() {
self.tableView.register(PCell.self, forCellReuseIdentifier: "cell")
}
}
在添加这个覆盖函数之后,我并没有在dequeueReusableCell上崩溃,但是现在应用程序崩溃了,因为出口变量titleLabel是nil
因此,我猜它没有得到正确的单元格实例,因为使用了override registerCell()函数。但如果没有它,应用程序也会崩溃
我做错了什么
我搜索了谷歌,但没有得到任何结果。您似乎试图测试
UITableView
的cellForRowAt:
方法。这不是你想要的。您想测试您的PCell
类。
为此,使用超类initinit(样式:reuseIdentifier:)
实例化一个PCell
。然后调用您自己的方法,如pcell.doSomethingthatsetTitle()
,并断言单元格的标题是您所期望的
编辑:
您能否详细说明您的答案,可能是一些示例代码。但您的代码是在单元测试函数本身中单独设置模型的。所以基本上它不会运行cellforrow函数,这完全违背了单元测试的目的。那么你想测试什么呢?代表还是单元?那么您的
单元格for rowat:
看起来像什么?我想测试一下单元格。我已经在问题中添加了cellforrow函数。很抱歉,没有看到您的实现。所以,如果要测试cell,为什么要调用委托的方法?相关文档说明:«如果您为指定的标识符注册了一个类,并且必须创建一个新的单元格,则此方法通过调用其init(style:reuseIdentifier:)方法来初始化单元格。对于基于nib的单元,此方法从提供的nib文件加载单元对象。如果现有单元格可重复使用,此方法将调用单元格的prepareForReuse()方法。«在测试中,直接初始化单元格,而不使用delegated。当从情节提要加载UIViewController
时,所有输出都会自动填充。当您在测试代码中显式实例化视图控制器时,您将丢失所有设置。这可能导致您当前的问题。(你可以尝试从UIStoryboard
对象创建它,但是你将无法使用模拟的VC子类。)@PauloMattos你可以发布一个答案吗。
func testTitleForPCells() {
let cell = PCell(style: .default, reuseIdentifier: "anything")
let model = Model(title: "FOO")
cell.setMyModel(model)
XCTAssertEqual(cell.titleLabel.text, model.title)
}