Tests for custom UITableViewCell, cellForRowAtIndexPath crashes with nil outlets

后端 未结 4 970
夕颜
夕颜 2021-01-21 22:58

I have a ViewController that contains a tableView. Since I need to keep the code well covered with tests, I need to write a test for [tableView:cellForRowAtIndexPath]

         


        
相关标签:
4条回答
  • 2021-01-21 23:37

    There are two separate concepts, the tableView and the dataSource. TableView is just a view, and has cells which are views as well. DataSource is the data provider of the tableView, and the only component responsible for data. In your test example, you call a tableView.cellForRowAtIndexPath function in order to get a cell, in a specific indexPath. Based on official docs, this function will return nil if the cell is not visible. So this function should be used, only when you know that the table is visible. In your example, you are trying to test that your table will load data properly. When referring to data, data source is the first thing that should come to your mind. So you need to test that the dataSource will bind the correct information to your cells. As a result you call controller.tableView.dataSource(controller.tableView, cellForRowAt: IndexPath(row: 0, section: 0)))

    0 讨论(0)
  • 2021-01-21 23:40

    There are a number of things that could be going wrong here. Some possibilities:

    1. tableView itself could be nil.
    2. No cell prototype in the nib or storyboard with the reuse identifier in question.
    3. You haven't registered a cell class with the reuse identifier in question.
    4. Cell allocation fails for some other reason, such as lack of memory.
    5. Some class, such as the table cell class, not included in the test target. (This would usually cause a build error rather than a crash.)
    6. Cell's .xib file not included in the test target.
    7. Relevant objects in .xib aren't connected to the proper outlets.
    8. Your crash is happening because you're trying to allocate a new cell in your tableView:cellForRowAtIndexPath: method. That used to be necessary if no cells were available for reuse, but these days a properly configured table will instantiate new cells as needed, and IIRC instantiating your own can cause a crash.
    0 讨论(0)
  • 2021-01-21 23:41

    Step 1: Go to Identity Inspector of your view controller in storyboard and give it a storyboard id. Ex: "vcIdentifier"

    Step 2: You have get the instance of your storyboard in Unit test

    Step 2 : Instantiate your view controller via storyboard instance from step 2

    Step 3 : Get access to your table view from the viewcontroller and pass it to 'cellForRowAt' method in your test. Please see below a sample code:

        let storyboard = UIStoryboard(name: "Main", bundle:nil)
        let newsViewController: UITableViewController = storyboard.instantiateViewController(identifier: "vcIdentifier")
        return newsViewController.tableView
    
    0 讨论(0)
  • 2021-01-21 23:42

    For me, (Swift 3) I had to call the cellForRow datasource cellForRowAt function instead of accessing straight from the tableView.cellForRow function

    //this 
    let cell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: 0, section: 0))
    
    //instead of this
    let cell = controller.tableView.cellForRow(at: IndexPath(row: 0, section: 0))
    
    0 讨论(0)
提交回复
热议问题