[英]Testing if UIAlertController has been presented
我有一個協議,用於允許我的 ViewControllers 顯示警報。
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 generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccurred()
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)
}
}
我稱之為
@objc private func didTapLogout() {
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: { [weak self] result in
guard result else { return }
self?.presenter.logout()
}
)
}
我想編寫一個單元測試來在調用時斷言,呈現的視圖控制器是UIAlertController
。
我正在嘗試類似的東西,但它沒有通過
func test_renders_alert_controller() {
sut.show()
XCTAssertNotNil(sut.presentedViewController)
}
class MockViewController: UIViewController, Alertable {
var presentViewControllerTarget: UIViewController?
func show() {
presentAlert(title: nil, message: "Are you sure you want to logout?", actions:
[AlertableAction(title: "No", style: .cancel, result: false)],
completion: nil
)
self.presentViewControllerTarget = self.presentedViewController
}
}
在運行斷言之前,您需要等待UIAlertController
完全可見。
查看XCTWaiter 。
嘗試類似以下內容:
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")
}
ViewControllerPresentationSpy通過捕獲將用於呈現警報的信息來避免緩慢、不穩定的單元測試,而不實際呈現任何警報。 您只需要創建一個 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"),
]
)
此驗證方法檢查:
.alert
默認情況下)您可以按名稱調用每個操作:
try alertVerifier.executeAction(forButton: "Yes")
(將測試標記為throws
。如果沒有給定名稱的按鈕,則測試將失敗。)
試試看它與 1.5 秒超時相比有多快。 還要比較你可以測試多少。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.