Reputation: 5441
I'm trying to unit test a function which presents a view outside a viewController:
public func presentInOwnWindow(animated: Bool, completion: (() -> Void)?) {
let alertWindow = UIWindow(frame: UIScreen.main.bounds)
alertWindow.rootViewController = UIViewController()
alertWindow.windowLevel = UIWindowLevelAlert + 1;
alertWindow.makeKeyAndVisible()
alertWindow.rootViewController?.present(self, animated: animated, completion: completion)
}
so far all I can think about how to unit test it is like this:
func test_presentInOwnWindow () {
let presented = sut.presentInOwnWindow(animated: true) {}
XCTAssertNotNil(presented)
}
I've tried passing a bool for the completion block :
completion: ((Bool) -> Void)
but since its invoking the completion for:
rootViewController?.present
I get the error:
Cannot convert value of type '((Bool) -> Void)?' to expected argument type '(() -> Void)?'
Any idea how to unit test the function properly?
Upvotes: 0
Views: 2974
Reputation: 20980
Several options to try:
present(_, animated, completion)
to capture what was presented. I do this for UIAlertControllers https://qualitycoding.org/testing-uialertcontroller/ but that's because UIAlertControllers are so common. It may not be worth the trouble for your custom window.makeKeyAndVisible
and present
probably don't produce immediate effects. Instead, they schedule the work. So you can try pumping the run loop with RunLoop.current.run(until: Date())
. This works for activating text fields, but I don't know if it will work for you.waitForExpectations
with a small timeout. As I note in https://qualitycoding.org/asynchronous-tests/, don't do any assertions in your expectation handler. Instead, capture the information you want and fulfill
the expectation. Then assert against what you've captured.Upvotes: 2
Reputation: 32815
Unit testing code that has side effects can be incredibly hard, especially if the side effects involve hardware, like the device screen. For this reason UI components are not suitable for unit testing, since they usually involve GPU operations.
Now, if you really want to test the component, you can go via two routes:
Conclusion: unit test the business code and let QA test the UI behaves as expected.
Upvotes: 0