[英]In XCTest: how to test that a function forced execution onto main thread
[英]How to test a function that gets into the main thread in Swift with RxSwift and XCTest?
我在测试View时遇到了这个问题:
在我的ViewModel中,我调用一个异步操作,当响应到达时,我使用PublishSubject
在View中进行更改。 在我的视图中,我调用DispatchQueue.main.async
以隐藏或显示按钮。
视图模型
let refreshButtons = PublishSubject<Bool>(true)
refreshButtons.onNext(true)
视图
model.refreshButtons.asObservable()
.subscribe(onNext: {
[unowned self] success in
self.updateButtons(success)
})
.addDisposableTo(disposable)
private func updateButtons(_ show:Bool) {
DispatchQueue.main.async{
button.isHidden = !show
}
}
现在,我不知道如何对refreshButtons.onNext(true)
将隐藏或显示我的按钮进行单元测试。
我能想到的解决方案是:
我该如何解决? 先感谢您。
您可以在单元测试中使用基于谓词的异步期望,以等待按钮不再被隐藏。
func testButtonIsHidden() {
// Setup your objects
let view = ...
let viewModel = ...
// Define an NSPredicate to test your expectation
let predicate = NSPredicate(block: { input, _ in
guard let _view = input as? MyView else { return false }
return _view.button.isHidden == true
})
// Create an expectation that will periodically evaluate the predicate
// to decided whether it's fulfilled or not
_ = expectation(for: predicate, evaluatedWith: view, handler: .none)
// Call the method that should generate the behaviour you are expecting.
viewModel.methodThatShouldResultInButtonBeingHidden()
// Wait for the
waitForExpectationsWithTimeout(1) { error in
if let error = error {
XCTFail("waitForExpectationsWithTimeout errored: \(error)")
}
}
}
值得注意的是,您传递给NSPredicate
的值应该是一个class
。 那是因为类是通过引用传递的,所以谓词块中的值将与视图模型所触及的值相同。 如果要传递通过副本传递的struct
或enum
,则谓词块将在运行安装代码时按原样接收值的副本,并且它将始终失败。
相反,如果您更喜欢使用@Randall Wang在其答案中建议的UI测试,则此文章可能对您有用:“ 如何在Xcode 7中测试UI更改 ”。 完全公开,我写了那个帖子。
首先,您不需要测试私有方法
如果要测试按钮是否隐藏,请尝试进行UI测试
这是UI测试的WWDC。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.