2015-06-14 2 views
0

У меня есть ViewController, который содержит tableView. Поскольку мне нужно держать код хорошо покрытое тесты, мне нужно написать тест для [Tableview: cellForRowAtIndexPath]Тесты для пользовательских UITableViewCell, cellForRowAtIndexPath сбой с выводами nil

import UIKit 

class MainViewController: UIViewController, UITableViewDataSource { 

    @IBOutlet weak var tableView: UITableView! 

    var source = [ 
     Country(name: "USA", capital: "Washington, D.C."), 
     Country(name: "Argentina", capital: "Buenos Aires"), 
     Country(name: "Mexico", capital: "Mexico, D.F.") 
    ] 
    let cellIdentifier = NSStringFromClass(MainViewController.self) 

    init() { 
     super.init(nibName: "MainViewController", bundle: nil) 
    } 

    required init(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let nib = UINib(nibName: "CustomCell", bundle: nil) 
     tableView?.registerNib(nib, forCellReuseIdentifier: cellIdentifier) 
     tableView.dataSource = self 
     } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return source.count 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? CustomCell 
     if let cell = cell { 
      cell.countryLabel.text = source[indexPath.row].name 
      cell.capitalLabel.text = source[indexPath.row].capital 
      return cell 
     } 
     return CustomCell() 
    } 
} 

struct Country { 
    var name: String 
    var capital: String 
} 

Тесты выглядеть следующим образом:

import UIKit 
import XCTest 

class MainViewControllerTests: XCTestCase { 

    var controller: MainViewController! 

    override func setUp() { 
     super.setUp() 

     controller = MainViewController() 
     controller.view.description 
    } 

    override func tearDown() { 
     super.tearDown() 
    } 

    func testTableViewOutlet() { 
     XCTAssertNotNil(controller.tableView) 
    } 

    func testTableViewCellForRowAtIndexPath() { 
     let indexPath = NSIndexPath(forRow: 0, inSection: 0) 

     let cell = controller.tableView(controller.tableView, cellForRowAtIndexPath: indexPath) as! CustomCell 

     XCTAssertEqual(cell.countryLabel.text!, "USA") 
     XCTAssertEqual(cell.capitalLabel.text!, "Washington, D.C.") 
    } 
} 

я получаю следующее сообщение об ошибке при выполнении тестов:

Test Case '-[CustomTableViewCellTests.MainViewControllerTests testTableViewCellForRowAtIndexPath]' started. 
fatal error: unexpectedly found nil while unwrapping an Optional value 

этой функция намекала испытание в течение нескольких месяцев в моем производственном применении, так как [dequeueReusableCellWithIdentifier] возвращает NIL только при запуске сюда m испытаний. На самом деле я пробовал много различных подходов я прочитал в StackOverflow, как:

  1. Создание CustomCell когда [dequeueReusableCellWithIdentifier] возвращает нильполугруппы
  2. Загрузка СИБ для CustomCell с помощью temporaryController и захватывая вид, который, как предполагается, для подключения к ячейке

Суть в том, что я приближаюсь к решению, я создаю объект CustomCell, но выходы для ячейки остаются равными нулю. Я не нашел фрагмент кода, который бы реализовал выходы в инициализированные элементы, чтобы я мог пройти тесты.

Я включаю в себя основной проект iOS со своим собственным git, который содержит код, который я здесь включил. Это UIViewController, который содержит UITableView, который отображает данные с помощью пользовательского UITableViewCell. Я надеюсь найти решение, которое реализует пользовательскую ячейку с ее выходами, чтобы пройти тест.

источник репо Git: https://bitbucket.org/jallauca/customcell/src

клонировать Git репо:

git clone https://bitbucket.org/jallauca/customcell.git 
+0

Всякий раз, когда вы задающим вопрос об ошибке или аварии , пожалуйста, также включайте любое сообщение журнала, которое объясняет крах и, возможно, соответствующую часть трассировки стека. – Caleb

+0

Мой веб-браузер предупреждает меня, что ваши ссылки указывают на возможный фишинговый сайт. Пожалуйста, разместите соответствующий код напрямую, а не попросите людей посмотреть его в другом месте. – Caleb

+0

Мое первое предположение, что представление не загружено. Просто создание экземпляра контроллера из xib/раскадровки не загружает весь вид или не соединяет все выходы. Доступ к свойству view может выполнять работу, хотя при тестировании этого пути остается открытым вопрос - так как многие поведения могут быть просто неопределенными и не имеют смысла, например, запрашивать состояние пользовательского интерфейса для элементов, которые никогда не были частью дерева представлений. – Eiko

ответ

0

Есть целый ряд вещей, которые могли бы идти неправильно здесь. Некоторые возможности:

  1. tableView само может быть ноль.
  2. Отсутствует прототип клетки в нибе или раскадровке с указанным идентификатором повторного использования.
  3. Вы не зарегистрировали класс ячейки с указанным идентификатором повторного использования.
  4. Выделение ячеек происходит по другой причине, например, нехватка памяти.
  5. Некоторые классы, такие как класс ячейки таблицы, не входят в тестовую цель. (Это обычно приводит к ошибке построения, а не к сбою.)
  6. Файл .xib Cell не входит в тестовую цель.
  7. Релевантные объекты в .xib не подключены к соответствующим выходам.
  8. Ваша авария происходит, потому что вы пытаетесь выделить новую ячейку в свой метод tableView:cellForRowAtIndexPath:. Это было необходимо, если бы не было доступных ячеек для повторного использования, но в эти дни правильно настроенная таблица будет создавать новые ячейки по мере необходимости, а экземпляр IIRC, создающий ваши собственные, может привести к сбою.
+0

Я включил два основных файла источника для разработчиков, которым нравится видеть код внутри форума. 1. tableView не ноль, как показывает тест. 2. Я не использую раскадровку, но xib, но я регистрирую класс ячейки в viewDidLoad. Должен ли я также делать это в xib? 3. Я зарегистрировал класс, как показано сейчас в коде. 4. В этом случае я могу отказаться от недостатка памяти. 5. Все классы включены в тестовый объект, я дважды проверял. 6. То же, что и 5. –

+0

Я рад, что вы можете указать, что не так с кодом. Можете ли вы предоставить шаги, которые мне нужно сделать, чтобы исправить это? В частности, «Соответствующие объекты в .xib не подключены к соответствующим выходам». Что мне не хватает? –

+0

Это просто возможная проблема. Я не проверял ваш .xib, чтобы проверить, что объекты подключены к их выходам. Вы должны быть в состоянии сделать это сами. Если вы обнаружите, что они не подключены к своим выходам, подключите их! Подумайте о приведенном выше списке в качестве элементов для проверки, а не о вещах, которые определенно не соответствуют вашему коду. – Caleb

1

Для меня, (Swift 3) Я должен был вызвать функцию cellForRow DataSource cellForRowAt вместо доступа прямо из функции tableView.cellForRow

//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)) 
Смежные вопросы