I am trying write a test to check if a presentModally segue is dismissed or present using thenavigationController. MessageVC is the modal I want to test if it is present or dismissed. However, after performSegue, the topViewController did not change to MessageVC.
Contact Storyboard Controller (ContactViewController):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "Message":
let navigationController = segue.destination as! UINavigationController
let messageVC = navigationController.topViewController as! MessageViewController
// Set the modal view controller to be the delegate of the presentationController for this presentation,
// so that modal view controller can respond to attempted dismissals
navigationController.presentationController?.delegate = messageVC
}
Test:
var messageVC = MessageViewController()
override func setUp() {
let storyboard = UIStoryboard(name: "Contact", bundle: Bundle.main)
let navigationController = storyboard.instantiateInitialViewController() as! UINavigationController
navigationController.topViewController.performSegue(withIdentifier: "Message", sender: self)
}
func testModalPresent() {
}
This will most likely be due to the that you are calling executing asynchronously. It probably doesn't even get a chance to execute before your test finishes.
With this sort of thing you really have two choices:
Update your test with XCTest asynchronous expectations so that it allows the code to execute and waits for the expected result.
Re-write your test as a UI test.
Either one is not going to be straight forward and will depend on your skills as to how well it will work for you. However both techniques are worth learning if you don't already know them.
Test expectations will help you in many asynchronous situations - network code, async APIs such as promises, reactive, and Apple's Combine.
UI testing will help with ensuring your app functions as expected from a users point of view.