繁体   English   中英

如何测试在UIAlertController的完成处理程序中调用的方法?

[英]How can I test the method called in the completion handler of a UIAlertController?

我有一个附加到UIViewController的协议,我希望允许该UIAlertController的演示。

import UIKit

struct AlertableAction {
    var title: String
    var style: UIAlertAction.Style
    var result: Bool
}

protocol Alertable {
    func presentAlert(title: String?, message: String?, actions: [AlertableAction], completion: ((Bool) -> Void)?)
}

extension Alertable where Self: UIViewController {
    func presentAlert(title: String?, message: String?, actions: [AlertableAction], completion: ((Bool) -> Void)?) {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        actions.forEach { action in
            alertController.addAction(UIAlertAction(title: action.title, style: action.style, handler: { _ in completion?(action.result) }))
        }
        present(alertController, animated: true, completion: nil)
    }
}

然后,只要我想发出警报,就可以在UIViewController调用此方法

   self?.presentAlert(
        title: nil, message: "Are you sure you want to logout?",
        actions: [
            AlertableAction(title: "No", style: .cancel, result: false),
            AlertableAction(title: "Yes", style: .destructive, result: true)],
        completion: { result in
            guard result else { return }
            self?.viewModel.revokeSession()
        }
    )

我试图在XCTestCase中断言单击“ ”会在我的视图模型上调用正确的方法。

我知道UITest将允许我测试警报是否可见,然后点击“ 是”,我将重定向到注销路径,但是我对测试方法本身非常感兴趣。

我不确定如何在代码中对此进行测试。

我试图在XCTestCase中断言,单击“是”会在我的视图模型上调用正确的方法……我对测试方法本身非常感兴趣。

实际上,目前尚不清楚您希望测试什么。 弄清楚(实际上需要测试什么?)是大部分工作。 您知道当标题为“是”时resulttrue ,因此无需测试有关此特定警报上实际点击的任何内容。 也许您要测试的只是这样:

    { result in
        guard result else { return }
        self?.viewModel.revokeSession()
    }

换句话说,您想知道resulttrue时将发生什么, resultfalse时将发生什么。 如果是这种情况,只需将匿名函数替换为实函数(方法):

func revokeIfTrue(_ result:Bool) {
    guard result else { return }
    self?.viewModel.revokeSession()
}

并重写您的presentAlert以使该方法完成:

self?.presentAlert(
    title: nil, message: "Are you sure you want to logout?",
    actions: [
        AlertableAction(title: "No", style: .cancel, result: false),
        AlertableAction(title: "Yes", style: .destructive, result: true)],
    completion: revokeIfTrue
)

现在,您已经将该功能分解为可以独立测试的功能。

使用ViewControllerPresentationSpy ,您的测试可以说

let alertVerifier = AlertVerifier()

创建验证器。 然后调用presentAlert函数。 接下来,打电话

alertVerifier.executeAction(forButton: "Yes")

执行给定的动作。 最后,调用捕获的闭包:

alertVerifier.capturedCompletion?()

并验证预期结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM