Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 测试是否已显示UIAlertController_Swift_Xctest_Uialertcontroller - Fatal编程技术网

Swift 测试是否已显示UIAlertController

Swift 测试是否已显示UIAlertController,swift,xctest,uialertcontroller,Swift,Xctest,Uialertcontroller,我有一个允许ViewController显示警报的协议 导入UIKit 结构AlertableAction{ 变量标题:字符串 变量样式:UIAlertAction.style var结果:Bool } 协议警报{ func presentAlert(标题:字符串?,消息:字符串?,操作:[AlertableAction],完成:((Bool)->Void)?) } 扩展可报警,其中Self:UIViewController{ func presentAlert(标题:字符串?,消息:字符串?,

我有一个允许ViewController显示警报的协议

导入UIKit
结构AlertableAction{
变量标题:字符串
变量样式:UIAlertAction.style
var结果:Bool
}
协议警报{
func presentAlert(标题:字符串?,消息:字符串?,操作:[AlertableAction],完成:((Bool)->Void)?)
}
扩展可报警,其中Self:UIViewController{
func presentAlert(标题:字符串?,消息:字符串?,操作:[AlertableAction],完成:((Bool)->Void)?){
let生成器=反馈生成器(样式:。中等)
生成器
让alertController=UIAlertController(标题:标题,消息:消息,首选样式:。警报)
actions.forEach{中的操作
addAction(UIAlertAction(标题:action.title,样式:action.style,处理程序:{正在完成?(action.result)}))
}
存在(alertController,动画:真,完成:无)
}
}
我把这叫做

@objc private func didTapLogout(){
展示员(
标题:无,消息:“您确定要注销吗?”,
行动:[
AlertableAction(标题:“否”,样式:。取消,结果:false),
AlertableAction(标题:“是”,样式:。破坏性,结果:真),
],
完成:{[弱自我]导致
保护结果else{return}
self?.presenter.logout()
}
)
}
我想编写一个单元测试来断言当调用它时,显示的视图控制器是
UIAlertController

我试过类似的东西,但没有通过

func测试呈现警报控制器(){
sut.show()
XCTASERTNOTNIL(sut.presentedViewController)
}
类MockViewController:UIViewController,可报警{
var PresentViewController目标:UIViewController?
func show(){
presentAlert(标题:nil,消息:“您确定要注销吗?”,操作:
[AlertableAction(标题:“否”,样式:。取消,结果:false)],
完成日期:无
)
self.presentViewControllerTarget=self.presentdviewcontroller
}
}

在运行断言之前,需要等待
UIAlertController
完全可见

退房

请尝试以下方法:

    let nav = UINavigationController.init(rootViewController: sut)

    sut.show()

    let exp = expectation(description: "Test after 1.5 second wait")
    let result = XCTWaiter.wait(for: [exp], timeout: 1.5)
    if result == XCTWaiter.Result.timedOut {
        XCTAssertNotNil(nav.visibleViewController is UIAlertController)
    } else {
        XCTFail("Delay interrupted")
    }
通过捕获用于显示警报的信息而不实际显示任何警报,避免了缓慢、不稳定的单元测试。您只需创建一个AlertVerifier,然后调用显示警报的任何内容:

let alertVerifier = AlertVerifier()

sut.show()

alertVerifier.verify(
    title: nil,
    message: "Are you sure you want to logout?",
    animated: true,
    presentingViewController: sut,
    actions: [
        .cancel("No"),
        .destructive("Yes"),
    ]
)
此验证方法检查:

  • 这一警报以动画形式呈现
  • 显示视图控制器是正在测试的系统
  • 警报标题
  • 警报消息
  • UIAlertController.style的首选样式(
    .alert
    默认)
  • 每个动作的标题和风格
您可以按名称调用每个操作:

try alertVerifier.executeAction(forButton: "Yes")
(将测试标记为
抛出
。如果没有具有给定名称的按钮,测试将失败。)

试试看它与1.5秒超时相比有多快。还要比较你能测试多少