[英]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.