2017-02-21 13 views
1

Итак, у меня есть раскадровка с UITableView. Существует прототип ячейки с шоу Segue подключили к другой UIViewControllerКак вы тестируете UIStoryBoard segue запускается didSelectRow (at :)

Пример enter image description here

  • Идентификатор ячейки "CellOne"
  • The перетекает не имеет идентификатора
  • Мой класс dataSource и делегат для tableView.

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

import UIKit 

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 
    @IBOutlet weak var tableView: UITableView! 

    func numberOfSections(in tableView: UITableView) -> Int { 
     return 1 
    } 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return 2 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     return tableView.dequeueReusableCell(withIdentifier: "CellOne", for: indexPath) 
    } 

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
     print("Selected the row") 
    } 
} 

Обычно я бы проверить его swizzling подготовиться к Segue захватить назначения ViewController и все остальное, что мне нужно, но называя tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) программно не вызывает код в подготовке для segue.

Можно ли проверить, что выбор Cell One запускает раскладку segue без добавления идентификатора segue и вызывает его явно из prepareForSegue?

+0

эй, ваш вопрос непонятен! почему вы хотите проверить, что segue запускается командой didSelectRow? Это очевидно, поскольку в этом VC только один раз. Итак, ваш вопрос, чтобы определить, какие триггеры tableviewcell готовят к настройке? –

+0

@JenJose это надуманный пример, у реального проекта есть еще много ячеек, пользовательских ячеек и т. Д. –

+0

У меня такая же проблема, вы нашли решение? –

ответ

1

Если tableViewCell это единственное, что вызывает переход к месту назначения, вы можете использовать является или в:

if let destination = segue.destination as? MyViewController, 
    let indexPath = tableView.indexPathForSelectedCell { 
    destination.detail = model[indexPath.row] 
} 

В противном случае, если вам нужно неоднозначность вы можете проверить класс отправителя с является или как

0

Обновлено: Длинные s Короче, нет отличного способа сделать это. Что затрудняет то, что, хотя большинство элементов управления, которые мы использовали для тестирования, имеют действие и отправителя, прикосновение к UITableViewCell является другой парадигмой.

Тем не менее, наличие идентификатора segue в основном является предварительным условием для любой стратегии.

Один из способов получить ссылку на ячейку и вызовите performSegue(withIdentifier:,sender:):

class ViewControllerTests: XCTestCase { 

    func testClickingACell() { 
     let controller = UIStoryboard(name: "ViewController", bundle: nil).instantiateInitialViewController() as! ViewController 
     let cell = controller.tableView.dataSource?.tableView(controller.tableView, cellForRowAt: IndexPath(row: 0, section: 0)) 

     controller.performSegue(withIdentifier: "MySegue", sender: cell) 

     XCTAssertNotNil(controller.presentedViewController as? TheDestinationViewController) 
    } 
} 

Другим (полностью избыточен) способом будет иметь пользовательские ячейки, где вы справиться со всеми вашей собственной сенсорной логикой. Это было бы безумным, но это была возможность, и он открыл бы больше возможностей для тестирования. Я не собираюсь показывать этот путь, потому что это был бы безумный способ сделать это.

Другой способ - использовать другую архитектуру, которая избавляется от UIKit и позволяет тестировать только логику performSegue. Пример:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 

    @IBOutlet var myTableView: UITableView! 
    var navigator: UIViewController? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     navigator = self 
    } 

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
     navigator?.performSegue(withIdentifier: "MySegue", sender: nil) 
    } 

} 

Это позволяет сделать что-то вроде этого в тестах:

class MockNavigator: ViewController { 
    var performSegueCalled = false 
    var performSegueIdentifier: String? 

    override func performSegue(withIdentifier identifier: String, sender: Any?) { 
     performSegueCalled = true 
     performSegueIdentifier = identifier 
    } 
} 

func testExample() { 
    let controller = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as! ViewController 
    controller.loadViewIfNeeded() 

    // Need to keep a reference to be able to assert against it 
    let mockNavigator = MockNavigator() 

    controller.navigator = mockNavigator 

    controller.tableView(controller.myTableView, didSelectRowAt: IndexPath(row: 0, section: 0)) 

    XCTAssertTrue(mockNavigator.performSegueCalled) 
    XCTAssertEqual(mockNavigator.performSegueIdentifier, "MySegue") 
} 

Другой способ структурирования кода, чтобы избежать UIKit использовать что-то вроде шаблона вид модели-координатор для создания и протестируйте viewModel.В основном вы бы сказали своему координатору, что ячейка выбрана, и координатор обновит модель представления с желаемым идентификатором сегмента. Таким образом, вы можете протестировать объект координатора и быть в основном уверены, что вы активируете правильное segue, если координатор подключен. Простой ручной тест скажет вам об этом.

В псевдокоде:

struct ViewModel { 
    let labelText: String 
    let segueIdentifier: String 
} 

class Coordinator { 
    var data = [YourObject]() 
    var viewModel = ViewModel(labelText: "", segueIdentifier: "") 

    func selectedItem(at row: Int) { 
     let item = data[row] 

     // Do some logic to figure out which identifier you want 
     var segueIdentifer: String 
     if item == whatever { 
      segueIdentifier = "something" 
     } 
     viewModel = ViewModel(labelText: item.text, segueIdentifier: segueIdentifier) 
    } 
} 

Наверное, лучший способ это сочетание подходов. Используйте координатор с моделью просмотра, которая проверена сама по себе. Затем выполните тест, в котором вы используете UIKit для выбора ячейки и убедитесь, что издеваемое выполнение этого координатора используется, как ожидалось. Чем меньше единиц вы тестируете, тем легче будет.