Swift “我可以吗?”;“主线程”;是否从XCTestCase中使用?

Swift “我可以吗?”;“主线程”;是否从XCTestCase中使用?,swift,grand-central-dispatch,Swift,Grand Central Dispatch,在XCode中进行单元测试时,我发现我无法在另一个线程的主线程上运行代码。这个代码有什么问题?变量run未重置 import XCTest class TestMainThread: XCTestCase { override func setUpWithError() throws { } override func tearDownWithError() throws { } func testMain() throws {

在XCode中进行单元测试时,我发现我无法在另一个线程的主线程上运行代码。这个代码有什么问题?变量
run
未重置

import XCTest
class TestMainThread: XCTestCase {
    override func setUpWithError() throws {
    }
    override func tearDownWithError() throws {
    }
    
    func testMain() throws {
        var run = true
        DispatchQueue.main.async {
            // return to the main thread so can interact with UI
            run = false
        }
        while run {
            print("Running")
            usleep(1000000)
        }
    }
}

不能在XCTest中使用DispatchQueue。但是,您可以在测试的类中使用它,并在那里更改值

func operationToBeTested(completion: @escaping () -> Void) {
    ...
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
            completion()
        }
}

func test_operationToBeTested() {
    let exp = expectation(description: "asyncTest")
    XCTAssertFalse(mockView.isPrepareUICalled)
    mockClass.operationToBeTested {
        exp.fulfill()
        XCTAssertTrue(...)
    }
    waitForExpectations(timeout: 5)
}

p、 s.@Rob在评论中解释道,当我们编写“期望”时,我们在XCTests中使用DispatchQueue。

您的testMain()方法已经在主线程上运行。是的,您可以使用main queue,但是
while
循环的使用是不兼容的,如中所述。如果要等待将某些内容发送回主队列,请使用期望值。我不清楚您为什么坚持使用
while
循环模式。在最好的情况下,它效率低下,在最坏的情况下,它引入了死锁风险。“您不能在XCTest中使用
DispatchQueue
是什么意思?”?你可以。您只需要避免编写死锁的测试(例如,通过使用期望);您不能在测试函数中写入DispatchQueue.main.async{/},您需要改为写入“期望值”。当然,无论何时测试异步内容,都会使用期望值。因此,您可以在测试中使用
DispatchQueue
,但为了等待完成,您可以将它与预期一起使用。简言之,我同意人们会使用期望值,但暗示人们不能将GCD与期望值结合使用是误导或混淆的。这就是为什么我们甚至期望在测试中处理异步事情(比如
DispatchQueue
)的全部原因。