override func tearDownWithError() throws {
try super.tearDownWithError()
UIApplication.shared.keyWindow?.rootViewController = nil
}
func testNextStep_thirdPartyNewMemberWithEmail_showNameStep() {
let navigationController = MockNavigationController(rootViewController: UIViewController())
UIApplication.shared.keyWindow?.rootViewController = navigationController
}
Even though I set rootViewController as nil when tear down, navigationController doesn’t get deinit.
func testNextStep_thirdPartyNewMemberWithEmailAndName_hideNameHelperLabel() {
// Given
...
let navigationController = MockNavigationController(rootViewController: UIViewController())
UIApplication.shared.keyWindow?.rootViewController = navigationController
let expectation = XCTestExpectation(description: "push Login Stack View Controller")
navigationController.pushCompletion = { viewController in
expectation.fulfill()
// Then
...
}
// When
CreateSessionManager.shared.nextStep(...)
wait(for: [expectation])
}
class MockNavigationController: UINavigationController {
var pushCompletion: ((UIViewController) -> Void)?
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
if let pushCompletion = pushCompletion {
pushCompletion(viewController)
} else {
super.pushViewController(viewController, animated: animated)
}
}
}
func nextStep(...) {
UIViewController.current().navigationController?.pushViewController(LoginStackViewController())
}
So I changed pushViewController method not to really push when push a view controller for test. To setting rootviewcontroller as normal, when pushCompletion is not set, I made pushViewController method work as normal. Because in production code, there was a code to find top view controller of navigation controller of the window.