Неожиданное поведение 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)