首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何测试UIAlertController

如何测试UIAlertController
EN

Stack Overflow用户
提问于 2018-01-14 13:15:42
回答 3查看 5.7K关注 0票数 7

我正在测试一个呈现UIAlertController的函数,但是测试总是失败。该函数如下所示:

代码语言:javascript
复制
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)
  self.present(alert, animated: true, completion: nil)
}

由于此函数位于一个名为ShopViewController的类中,因此我假设测试此函数的正确方法是调用函数shopViewController.presentBuyingErrorDiaologue(),然后使用XCTAssertTrue(shopViewController.presentedViewController is UIAlertController)。但是,当我运行测试时,assert语句失败。测试UIAlertController是否是显示的视图的正确方法是什么?

EN

回答 3

Stack Overflow用户

发布于 2018-01-14 13:42:41

在测试其可见性之前,您应该等待UIAlertController完全呈现,因此您可以尝试按照以下方式更改测试:

代码语言:javascript
复制
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)
   }
}

您可以使用您的ShopViewController更改UIApplication.shared.keyWindow?.rootViewController

票数 6
EN

Stack Overflow用户

发布于 2018-01-16 14:32:32

在测试调用shopViewController.presentBuyingErrorDialogue()之前,

  1. ViewControllerPresentationSpy添加到测试 target
    1. import ViewControllerPresentationSpy
    2. Instantiate an AlertVerifier中

然后调用它的verify方法:

代码语言:javascript
复制
alertVerifier.verify(
    title: "Warning",
    message: "Error purchasing item, please retry this action. If that doesn't help, try restarting or reinstalling the app.",
    animated: true,
    presentingViewController: shopViewController,
    actions: [
        .default("OK"),
    ]
)

这将检查:

显示了一个警报,其中animation.

  • That显示的视图控制器是shopViewController.

  • The警报标题。

  • 警报标题首选样式为.alert (默认情况下)

  • 每个操作的标题和样式。

除了捕获值之外,AlertVerifier还允许您轻松地执行警告按钮的操作:

代码语言:javascript
复制
func test_alertOKButton() throws {
    shopViewController.presentBuyingErrorDiaologue()

    try alertVerifier.executeAction(forButton: "OK")

    // Test the results here
}

这些测试不需要等待任何期望,所以它们非常快。

票数 5
EN

Stack Overflow用户

发布于 2018-01-14 16:21:24

您可以使用present方法的completion参数来获取警报出现时的回调,从而确定是否显示了警报。(请注意,这种方法更多的是断言执行了正确的操作,而不是显示了正确的视图控制器类型)。

要实现这一点,您必须向presentBuyingErrorDialogue方法添加一个completion参数,但是您可以给它一个默认值nil,这样它就不会在非测试代码中打扰您。(当然,当它有意义时,您也可以在您的应用程序代码中使用它,例如在警报出现时启动背景动画)。

以下是修改后的视图控制器代码:

代码语言:javascript
复制
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的任何清理):

代码语言:javascript
复制
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)
  }
}

在应用程序代码中,您仍然可以像以前一样使用该方法,而不必提供该回调块:

代码语言:javascript
复制
let vc = ShopViewController()
vc.presentBuyingErrorDialogue()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48246885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档