Ios CellForRowatineXpath单元测试崩溃

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

我有一个简单的带有一些行的tableview。每一行都是一个带有xib文件的自定义单元格。我已经实现了委托和数据源,当我运行应用程序时,它工作正常。这就是我实现它的方式

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
类。 为此,使用超类init
init(样式: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)
}