簡體   English   中英

在 XCTest 中:如何測試 function 強制執行到主線程

[英]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 元素,如果不在主線程上強制執行,預計它會崩潰。 那么“沒有崩潰”是這里唯一可測試的條件嗎? 有更好的嗎?

當后台有外閉包,主線程有內閉包時,我們要兩個測試:

  1. 調用外部閉包。 等待期望。 等待 0.01 秒。 檢查是否執行了預期的工作。
  2. 調用外部閉包。 這一次,不要等待期望。 檢查工作是否未執行。

要使用此模式,我認為您必須更改代碼,以便測試可以直接調用外部閉包,而不必已經執行異步舞蹈。 這表明您的設計太深,無法在不進行某些更改的情況下進行測試。

想辦法讓中間的 object 捕獲閉包。 也就是說,不是直接調用DispatchQueue.global(qos: .background).async ,而是創建一個表示此操作的類型。 然后 Test Spy 版本可以捕獲閉包而不是將其分派到后台,以便您的測試可以直接調用它。 然后您可以使用異步等待測試對主線程的回調。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM