【发布时间】:2019-09-08 14:53:52
【问题描述】:
我学习 TTD,但在单元测试中遇到导航控制器问题。 当我尝试使用我的模拟控制器通过导航堆栈(pushViewController(ViewController,animated:))推送详细视图控制器时,在测试推送功能中不执行(它仅在第一次执行时,导航控制器初始化)。 在模拟 iPhone 上,应用程序正常工作。 在代码中 mockNavigationController 有值 pushVC,当 pushViewController 执行时会改变。 当用户点击单元格时,dataProvider(tableCell 的委托和数据源)向 ViewController(sut)发布通知,实现 showDetails 方法。
我会尝试从 navigationController 中获取 topViewController: sut.navigationController?.topViewController - 它返回 sut ViewController。 尽量不要在测试中初始化 navigationController。 sut.navigationController?.topViewController - 返回 nil。
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()
}
这个测试函数
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)
}
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)
}
还有 MockNavigationController
extension EatersListViewControllerTests {
class MockNavigationController: UINavigationController {
var pushedVC: UIViewController?
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
pushedVC = viewController
super.pushViewController(viewController, animated: animated)
}
}
}
我预计 XCTAssert 工作正常,但每次测试都在 XCTFail() 行上失败。我认为某处有错误,这里不知道。
XCTAssertNotNil(detailEaterVC.eaterNameLabel)
XCTAssertEqual(detailEaterVC.eaterData, eater1)
需要代码方面的帮助,我错了。感谢阅读。
【问题讨论】:
标签: ios swift unit-testing uinavigationcontroller mocking