Luk*_*uke 6 unit-testing swift uialertcontroller uialertaction
关于此主题有两个现有的问题,但它们并不是我所追求的。我为我的应用程序编写了一个Swift应用程序评级提示,其中显示了两个UIAlertController
实例,一个实例由另一个实例触发。
我现在正在尝试对此进行单元测试,并试图在测试中达到第二个警报。我编写了一个简单的间谍程序来检查第一个控制器,但是我想一种触发第一个警报的动作的方法,该警报又显示第二个。
我已经尝试过了alert.actions.first?.accessibilityActivate()
,但是似乎并没有在该操作的处理程序中打断–这就是我所追求的。
小智 7
一个不涉及更改生产代码以允许在单元测试中以编程方式轻敲UIAlertActions的解决方案,我在此SO答案中找到了该解决方案。
在谷歌搜索寻找答案时,在这里出现的问题以及此问题都会弹出,下面的解决方案使我有更多的时间查找。
将扩展名放在测试目标下面:
extension UIAlertController {
typealias AlertHandler = @convention(block) (UIAlertAction) -> Void
func tapButton(atIndex index: Int) {
guard let block = actions[index].value(forKey: "handler") else { return }
let handler = unsafeBitCast(block as AnyObject, to: AlertHandler.self)
handler(actions[index])
}
}
Run Code Online (Sandbox Code Playgroud)
这大致就是我所做的:
创建类的模拟版本以显示警报控制器,并在我的单元测试中使用此模拟。
覆盖我在非模拟版本中创建的以下方法:
func alertActionWithTitle(title: String?, style: UIAlertActionStyle, handler: Handler) -> UIAlertAction
Run Code Online (Sandbox Code Playgroud)在重写的实现中,将有关操作的所有详细信息存储在某些属性中(Handler
只是typealias'd () -> (UIAlertAction)
)
var didCreateAlert = false
var createdTitles: [String?] = []
var createdStyles: [UIAlertActionStyle?] = []
var createdHandlers: [Handler?] = []
var createdActions: [UIAlertAction?] = []
Run Code Online (Sandbox Code Playgroud)然后,在运行测试时,为了遍历警报的路径,我实现了一种callHandlerAtIndex
方法来遍历处理程序并执行正确的处理程序。
这意味着我的测试看起来像这样:
feedback.start()
feedback.callHandlerAtIndex(1) // First alert, second action
feedback.callHandlerAtIndex(2) // Second alert, third action
XCTAssertTrue(mockMailer.didCallMail)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3294 次 |
最近记录: |