![](/img/trans.png)
[英]How to test a function that gets into the main thread in Swift with RxSwift and XCTest?
[英]In XCTest: how to test that a function forced execution onto main thread
在 UI class 中,我有一个访问 UI 元素的方法,因此应该将其自身强制到主线程上。 这是我的意思的一个最小例子:
class SomeUI {
func doWorkOnUI() {
guard Thread.isMainThread else {
DispatchQueue.main.async {
self.doWorkOnUI()
}
return
}
print("Doing the work on UI and running on main thread")
}
}
在测试中,当然测试doWorkOnUI()
已经在主线程上运行的情况是没有问题的。 我只是这样做:
func testWhenOnMainThread() {
let testedObject = SomeUI()
let expectation = XCTestExpectation(description: "Completed doWorkOnUI")
DispatchQueue.main.async {
testedObject.doWorkOnUI()
expectation.fulfill()
}
wait(for: [expectation], timeout: 10.0)
// Proceed to some validation
}
那就是:强制执行到主线程。 等待它完成。 做一些检查。
但是如何测试相反的情况,即确保 function 在从后台线程调用时强制自己在主线程上运行?
例如,如果我做类似的事情:
...
DispatchQueue.global(qos: .background).async {
testedObject.doWorkOnUI()
expectation.fulfill()
}
...
我刚刚测试了 function从后台线程执行。 但是我没有明确检查它是否在主线程上运行。 当然,由于这个 function 访问 UI 元素,如果不在主线程上强制执行,预计它会崩溃。 那么“没有崩溃”是这里唯一可测试的条件吗? 有更好的吗?
当后台有外闭包,主线程有内闭包时,我们要两个测试:
要使用此模式,我认为您必须更改代码,以便测试可以直接调用外部闭包,而不必已经执行异步舞蹈。 这表明您的设计太深,无法在不进行某些更改的情况下进行测试。
想办法让中间的 object 捕获闭包。 也就是说,不是直接调用DispatchQueue.global(qos: .background).async
,而是创建一个表示此操作的类型。 然后 Test Spy 版本可以捕获闭包而不是将其分派到后台,以便您的测试可以直接调用它。 然后您可以使用异步等待测试对主线程的回调。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.