我正在测试一个呈现UIAlertController的函数,但测试仍然失败。这就是函数的样子:
func presentBuyingErrorDiaologue() {
let alert = UIAlertController(title: "Warning", message: "Error purchasing item, please retry this action. If that doesn't help, try restarting or reinstalling the app.", preferredStyle: .alert)
let okButton = UIAlertAction(title: "OK", style: .default)
alert.addAction(okButton)
self.present(alert, animated: true, completion: nil)
}
由于此函数位于名为ShopViewController的类中,因此我假设测试此函数的正确方法是调用函数shopViewController.presentBuyingErrorDiaologue()
,然后使用XCTAssertTrue(shopViewController.presentedViewController is UIAlertController)
。但是,当我运行测试时,assert语句失败。测试UIAlertController是呈现视图的正确方法是什么?
答案 0 :(得分:3)
在测试其可见性之前,您应该等待UIAlertController
完全呈现,因此您可能会尝试按照以下方式更改测试:
import XCTest
class UIAlertControllerTests: XCTestCase {
func presentBuyingErrorDialogue() {
let alert = UIAlertController(title: "Warning", message: "Error purchasing item, please retry this action. If that doesn't help, try restarting or reinstalling the app.", preferredStyle: .alert)
let okButton = UIAlertAction(title: "OK", style: .default)
alert.addAction(okButton)
UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true, completion: nil)
}
func testPresentBuyingErrorDialogue() {
self.presentBuyingErrorDialogue()
let expectation = XCTestExpectation(description: "testExample")
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
XCTAssertTrue(UIApplication.shared.keyWindow?.rootViewController?.presentedViewController is UIAlertController)
expectation.fulfill()
})
wait(for: [expectation], timeout: 1.5)
}
}
您可以使用UIApplication.shared.keyWindow?.rootViewController
更改ShopViewController
。
答案 1 :(得分:2)
#import <MockUIAlertController/QCOMockAlertVerifier.h>
添加到该桥接标题shopViewController.presentBuyingErrorDiaologue()
除了捕获值之外,QCOMockAlertVerifier还可以让您轻松执行具有给定标题的警报按钮的操作。
测试不需要等待期望,所以它们超级快。
在How to Test UIAlertControllers (and Control Swizzling)了解详情。
答案 2 :(得分:0)
您可以使用completion
方法的present
参数在出现警报时获取回调,从而确定是否显示警报。 (请注意,此方法更多是关于断言执行了正确的操作,而不是显示了正确的视图控制器类型)。
要实现此功能,您必须在completion
方法中添加presentBuyingErrorDialogue
参数,但是您可以为其设置默认值nil
,这样就不会打扰你的非测试代码。 (当然,您也可以在有意义的情况下在应用程序代码中使用它,例如在出现警报时启动背景动画)。
以下是视图控制器的修改代码:
class ShopViewController: UIViewController {
func presentBuyingErrorDialogue(completion: (() -> ())? = nil) {
let alert = UIAlertController(title: "Warning", message: "...", preferredStyle: .alert)
let okButton = UIAlertAction(title: "OK", style: .default)
alert.addAction(okButton)
self.present(alert, animated: true, completion: completion)
}
}
这是一个简单的测试可能看起来像(忽略rootViewController
的任何清理):
class ShopViewControllerTests: XCTestCase {
func testErrorAlert() {
let vc = ShopViewController()
UIApplication.shared.keyWindow?.rootViewController = vc
let exp = expectation(description: "shows alert")
vc.presentBuyingErrorDialogue {
exp.fulfill()
}
waitForExpectations(timeout: 1)
}
}
在应用程序代码中,您仍然可以像以前一样使用该方法,而无需提供该回调块:
let vc = ShopViewController()
vc.presentBuyingErrorDialogue()