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

标签 ios swift xctest uialertcontroller xctestcase

我有一个附加到 UIViewController 的协议(protocol),我希望允许呈现 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 中断言单击会在我的 View 模型上调用正确的方法。

我知道UITest将允许我测试警报是否可见,然后也许在点击时我会被重定向到注销路线,但是我真的很感兴趣测试方法本身。

但是我不确定如何在代码中测试它。

最佳答案

I am trying to assert within a XCTestCase that clicking Yes calls the correct method on my view model ... I am really interested in testing the method itself.

实际上仍然不清楚您到底想要测试什么。弄清楚这一点(实际上什么需要测试?)是最重要的战斗。您知道当标题为"is"时,结果true,因此无需测试有关实际点击此特定警报的任何内容。也许您要求测试的只是这样:

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

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

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
)

现在您已将函数分解为可独立测试的内容。

关于ios - 如何测试 UIAlertController 的完成处理程序中调用的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56922465/

相关文章:

html - 短信 : and mailto: failure on iPhone Safari Mobile Browser

ios - 核心图: latest 1. 6版本不包含位码

xcode - Xcode7 | Xcode UI测试|如何处理位置服务警报?

xcode - 在等待期望时使用 XCTFail 不会阻止超时

travis-ci - 如何更改 Travis CI 中的 xctool 目的地

ios - UITableViewController 上是否可以有 'sticky' 页脚?

ios - 在 iOS 上的 applicationDidBecomeActive() 后 Unity3D 应用程序崩溃

针对不同设备的 Xcode segues

ios - 覆盖不同类型的父类(super class)属性

swift - Swift 中是否提供键值观察 (KVO)?