I learning TTD, and have problem with navigation controller in Unit-testing. When I'm trying to push Detail View Controller through navigation stack (pushViewController(ViewController, animated:) ) with my mock controller, in test push function not perform (its perform only first time, when navigationController initialise). On simulation iPhone, app work correctly. In code mockNavigationController have value pushedVC, that changes when pushViewController perform. When user tap on cell, dataProvider (delegate and dataSource for tableCell) post notification to ViewController (sut), that implements showDetails method.
I'd try take topViewController from navigationController: sut.navigationController?.topViewController - it's return sut ViewController. Try not initialise navigationController in test. sut.navigationController?.topViewController - it's return nil.
This beginning of XCTestCase
var sut: EatersListViewController!
override func setUp() {
super.setUp()
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyBoard.instantiateViewController(withIdentifier: String(describing: EatersListViewController.self))
sut = vc as? EatersListViewController
sut.loadViewIfNeeded()
}
This test function
func testSelectedRowPushedDetailVC() {
let mockNavigationController = MockNavigationController(rootViewController: sut)
UIApplication.shared.keyWindow?.rootViewController = mockNavigationController
let eater1 = Eater(name: "Foo")
sut.dataProvider.manager!.addEater(eater: eater1)
sut.loadViewIfNeeded()
sut.tableView.delegate?.tableView?(sut.tableView, didSelectRowAt: IndexPath(row: 0, section: 0))
guard let detailEaterVC = mockNavigationController.pushedVC as? DetailEaterViewController else {
XCTFail()
return
}
detailEaterVC.loadViewIfNeeded()
XCTAssertNotNil(detailEaterVC.eaterNameLabel)
XCTAssertEqual(detailEaterVC.eaterData, eater1)
}
This function from ViewController
@objc func showDetails(withNotification notification: Notification) {
guard
let userInfo = notification.userInfo,
let eater = userInfo["eater"] as? Eater,
let detailEaterVC = storyboard?.instantiateViewController(withIdentifier: String(describing: DetailEaterViewController.self)) as? DetailEaterViewController else { return }
detailEaterVC.eaterData = eater
navigationController?.pushViewController(detailEaterVC, animated: true)
}
And MockNavigationController
extension EatersListViewControllerTests {
class MockNavigationController: UINavigationController {
var pushedVC: UIViewController?
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
pushedVC = viewController
super.pushViewController(viewController, animated: animated)
}
}
}
I'd expected that XCTAssert work correct, but every time test failed on XCTFail() line. I think somewhere error, and don't know here.
XCTAssertNotNil(detailEaterVC.eaterNameLabel)
XCTAssertEqual(detailEaterVC.eaterData, eater1)
Need help with code, where I wrong. Thanks for reading.