Неожиданное поведение XCTWaiter.wait

Для целей тестирования у меня есть следующая тестовая функция:

      func test_wait() {
    var string: String?
    DispatchQueue.main.async {
        string = "set"
        print("string set")
    }
    let notNilPredicate = NSPredicate(format: "self != nil")
    let notNilExpectation = expectation(for: notNilPredicate, evaluatedWith: string)
    print("start waiting")
    let waitResult = XCTWaiter.wait(for: [notNilExpectation], timeout: 5)
    XCTAssert(waitResult == .completed, "wait for notNilExpectation failed with result \(waitResult)")
}  

Этот тест не проходит.
Результат ожидания.timedOut, а журнал

      start waiting
string set
… : XCTAssertTrue failed - wait for notNilExpectation failed with result XCTWaiterResult(rawValue: 2)
Interrupting test  

Я не понимаю, почему ожидание не удается, хотяvar stringустановлен.
Однако тест проходит успешно , когда я комментируюDispatchQueue.main.async, т.е. когда я выполняю его блок синхронно. Журнал тогда

      string set
start waiting
Test Case '-[ShopEasyTests.CoreDataCloudKitContainerTest test_wait]' passed (1.087 seconds).  

Насколько я понимаю, асинхронная версия тестовой функции тоже должна работать.
Что не так?

1 ответ

Это предикат (и семантика захвата). Вы думаете, что передаете ссылку наstringв вашу предикатную оценку, но это не так; ты просто проходишь, и волшебным образом не будет не-nilв ближайшее время. Чтобы меньше путаться, перепишите как

      let notNilPredicate = NSPredicate {_,_ in string != nil }
let notNilExpectation = expectation(for: notNilPredicate, evaluatedWith: nil)
Другие вопросы по тегам