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

时间:2019-07-07 13:12:30

标签: ios swift xctest uialertcontroller xctestcase

我有一个要附加到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将允许我测试警报是否可见,然后点击,我将重定向到注销路径,但是我对测试该方法非常感兴趣本身。

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

2 个答案:

答案 0 :(得分:0)

  

我试图在XCTestCase中断言,单击“是”会在我的视图模型上调用正确的方法...我真的很想测试该方法本身。

实际上还不清楚您希望测试什么。弄清楚(实际上需要测试什么?)是大部分工作。您知道标题为“是”时Thread thread = new Thread(Butoon_Click(sender, ev)); thread.IsBackground = true; result,因此无需测试有关此特定警报的实际点击的任何内容。也许您要测试的只是这个:

true

换句话说,您想知道 { result in guard result else { return } self?.viewModel.revokeSession() } result时会发生什么,而truefalse时会发生什么。如果是这样,只需将匿名函数替换为实函数(方法):

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
)

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

答案 1 :(得分:0)

使用MockUIAlertController,您的测试可以说

let alertVerifier = QCOMockAlertVerifier()

创建验证程序。然后调用您的presentAlert函数。接下来,致电

alertVerifier.executeActionForButton(withTitle: "Yes")

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

alertVerifier.completion()

并验证预期结果。