Swift 在XCTest中:如何测试函数是否强制执行到主线程上
在UI类中,我有一个访问UI元素的方法,因此应该将其自身强制到主线程上。这里有一个最简单的例子来说明我的意思:Swift 在XCTest中:如何测试函数是否强制执行到主线程上,swift,multithreading,xctest,Swift,Multithreading,Xctest,在UI类中,我有一个访问UI元素的方法,因此应该将其自身强制到主线程上。这里有一个最简单的例子来说明我的意思: class SomeUI { func doWorkOnUI() { guard Thread.isMainThread else { DispatchQueue.main.async { self.doWorkOnUI() } return
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
}
也就是说:强制执行到主线程上。等待它完成。做一些检查
但是如何测试相反的情况,即当从后台线程调用函数时,如何确保函数强制自己在主线程上运行?
例如,如果我做了如下操作:
...
DispatchQueue.global(qos: .background).async {
testedObject.doWorkOnUI()
expectation.fulfill()
}
...
我刚刚测试了从后台线程执行的函数。但我没有明确检查它是否在主线程上运行。当然,由于此函数访问UI元素,因此如果不强制在主线程上执行,它可能会崩溃。那么,“无崩溃”是这里唯一可测试的条件吗?还有更好的吗?当后台有一个外部闭包,主线程有一个内部闭包时,我们需要两个测试:
为中间对象找到捕获闭包的方法。也就是说,不要直接调用
DispatchQueue.global(qos:.background).async
,而是创建一个表示此操作的类型。然后,测试间谍版本可以捕获闭包,而不是将其分派到后台,以便您的测试可以直接调用它。然后,您可以使用异步等待来测试对主线程的回调。当后台有一个外部闭包,而主线程上有一个内部闭包时,我们需要两个测试:
DispatchQueue.global(qos:.background).async
,而是创建一个表示此操作的类型。然后,测试间谍版本可以捕获闭包,而不是将其分派到后台,以便您的测试可以直接调用它。然后可以使用异步等待测试对主线程的回调