2016-04-19 36 views
1

我正在用Swift 2構建iOS應用程序,該應用程序使用自定義表格視圖單元格以及附加標籤,圖像視圖等(我們稱之爲類CustomTableViewCell)。我爲每個子視圖創建了類別故事板連接併爲該單元分配了一個標識符。我嘲笑了數據並試圖運行應用程序來檢查單元格是否正確映射,並且看起來沒問題。測試自定義TableViewCell的內容

問題是,我無法將出隊單元視爲CustomTableViewCell來測試其屬性的值。當我downcast從tableView(tableView, cellForRowAtIndexPath: indexPath)返回的單元格時,所有自定義屬性值都變爲nil,我的測試失敗。

這裏是我的代碼:

MyViewControllerTests.swift

func testShouldConfigureTableViewCellToDisplayNotification() { 
    // Given 
    sut.tableView = TableViewSpy() 

    let items = [ <some items to display> ] 
    sut.displayedItems = items 

    // When 
    let indexPath = NSIndexPath(forRow: 0, inSection: 0) 
    let cell = viewController.tableView(viewController.tableView, cellForRowAtIndexPath: indexPath) as! CustomTableViewCell 

    // Then 
    XCTAssertEqual(cell.detailLabel?.text, "foo", "A properly configured table view cell should display the notification detail") 
    XCTAssertEqual(cell.titleLabel?.text, "Bar", "A properly configured table view cell should display the notification title") 
    XCTAssertEqual(cell.dateLabel?.text, "15/04/2016", "A properly configured table view cell should display the notification date") 
    } 

MyViewController.swift

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cellIdentifier = "CustomTableViewCell" 
    let displayedItem = displayedItems[indexPath.row] 
    var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? CustomTableViewCell 
    if cell == nil { 
     cell = CustomTableViewCell(style: .Value1, reuseIdentifier: cellIdentifier) 
    } 
    cell!.dateLabel?.text = displayedItem.date 
    cell!.detailLabel?.text = displayedItem.detail 
    cell!.titleLabel?.text = displayedItem.title 
    return cell! 
    } 

CustomTableViewCell.swift

class CustomTableViewCell: UITableViewCell { 
    // MARK: Properties 
    @IBOutlet weak var dateLabel: UILabel! 
    @IBOutlet weak var detailLabel: UILabel! 
    @IBOutlet weak var titleLabel: UILabel! 

    override func awakeFromNib() { 
    super.awakeFromNib() 
     // Initialization code 
    } 

    override func setSelected(selected: Bool, animated: Bool) { 
     super.setSelected(selected, animated: animated) 

     // Configure the view for the selected state 
    } 

} 

回答

0

嘗試更換

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cellIdentifier = "CustomTableViewCell" 
    let displayedItem = displayedItems[indexPath.row] 
    var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? CustomTableViewCell 
    if cell == nil { 
     cell = CustomTableViewCell(style: .Value1, reuseIdentifier: cellIdentifier) 
    } 
    cell!.dateLabel?.text = displayedItem.date 
    cell!.detailLabel?.text = displayedItem.detail 
    cell!.titleLabel?.text = displayedItem.title 
    return cell! 
    } 

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cellIdentifier = "CustomTableViewCell" 
    let displayedItem = displayedItems[indexPath.row] 
    var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! CustomTableViewCell 
    cell.dateLabel.text = displayedItem.date 
    cell.detailLabel.text = displayedItem.detail 
    cell.titleLabel.text = displayedItem.title 
    return cell 
    } 

如果您已經連接你的正確INS故事板,然後這應該工作。否則,請檢查您是否爲您的單元正確分配了所有IBOutlet。

如果有什麼不工作,請檢查以下內容:

1)故事板中選擇您的。

2)在右側列中打開Identity Inspector(頂部的第3個標籤)。確保您的單元格的類別設置爲CustomTableViewCell

3)在屬性檢查器(第4個選項卡)中,確保單元格標識符拼寫正確。

4)在Connections inspector(最後一個選項卡)中,分配您定義的單元格的所有IBOutlet。

+0

這使得Xcode中拋出一些構建錯誤:'不能強迫非可選類型「CustomTableViewCell」'的展開價值,因爲我把它拆開當細胞被出隊。當我從屬性綁定中刪除所有這些解包時,運行測試時出現致命錯誤:''意外地發現零,而解包可選值「' – lerp90

+0

我的壞!檢查更新答案。問題在於使用「cell!」在出現細胞後:)​​ –

+1

這意味着你沒有在故事板中正確指定你的細胞。我現在將更新我的答案,提供您需要檢查的其他內容 –

0

從你的代碼示例看起來像你沒有註冊你的單元格重用。

tableView.registerClass(CustomTableViewCell.self, forCellReuseIdentifier: "CustomTableViewCell") 
+0

據我所知,如果我不使用storyboard進行單元類映射,我應該註冊該類。這些技術是否互補? – lerp90

+0

哦,對不起。你是對的。如果您使用的是原型單元,則不需要使用此代碼。在這種情況下,確保您在IB中添加了正確的單元標識符就足夠了。 另外一般你需要使用這種方法來獲得UITableView單元 let cell = tableView.cellForRowAtIndexPath(indexPath) 但是你直接調用了委託方法,如果你的表沒有顯示,它可以返回空單元格。我只能建議嘗試在UITableView委託方法中設置斷點,以瞭解發生了什麼問題。或者用VC代碼發佈示例項目。 –

+0

我試過你指出的內容,並得出結論說我的測試失敗了,當我嘗試向下轉換'cellForRow:atIndexPath'的結果時。 – lerp90