Ожидание нескольких асинхронных вызовов в setUp() XCTestCase
Мне нужно выполнить несколько звонков, прежде чем позволить test()
метод запуска. У меня есть блок завершения, и я использую waitForExpectations()
, Поскольку существует более одного асинхронного вызова, я использую счетчик. Я позволил expectation.fulfill()
произойдет только тогда, когда счетчик достигнет количества звонков.
override func setUp() {
super.setUp()
let exp = expectation(description: "waitForSetUp")
var counter = 0
// Issue an async request
self.addEventToCalendar(title: "Test1", description: "Description test1", startDate: NSDate().addingTimeInterval(-36000), endDate: NSDate()){(success, error) in
if (success) && (error == nil) {
counter = counter + 1
if(counter == 2){exp.fulfill()}
}
}
self.addEventToCalendar(title: "Test2", description: "Description test2", startDate: NSDate(), endDate: NSDate().addingTimeInterval(36000)){(success, error) in
if (success) && (error == nil) {
counter = counter + 1
if(counter == 2){exp.fulfill()}
}
}
waitForExpectations(timeout: 40, handler: nil)
}
Эта конструкция не работает. test()
Метод иногда запускается до возврата вызовов (не всегда).
Как я могу сделать setUp()
ждать возвращения нескольких асинхронных вызовов?
1 ответ
У меня был похожий случай. В итоге я решил вызвать несколько функций, которые добавляют ожидания для моих предпосылок и устанавливают разумные значения времени ожидания ожидания. В обработчиках завершения ожиданий я запустил следующий шаг моего алгоритма установки. После того, как все предварительные шаги пройдены, я начинаю реальную логику тестирования.
Прикрепление ссылки на Apple Docs.
РЕДАКТИРОВАТЬ: Пожалуйста, смотрите пример кода ниже:
class CommonTests: XCTestCase {
var validate: XCTestExpectation? = nil
func testMytest() {
validate(completion: {
loadSomeStuff(completion: { (list: [Stuff]?) in
// actual test
}
})
}
func validate(completion: @escaping ()->()) {
self.validateExpectation = self.expectation(description: "Setup")
// async operation can be fired here
// or if already started from somewhere else just wait for it to complete
self.waitForExpectations(timeout: 60) { (error: Error?) in
XCTAssert((error == nil), error?.localizedDescription ?? "Failed with unknown error")
completion()
}
}
func validateAsyncCompleted() {
self.validateExpectation?.fulfill()
}
func loadStuff(completion: @escaping ([Stuff]?)->()) {
// possible place for assertion or some other checks
let expectation = self.expectation(description: "loading")
DispatchQueue.global().async {
let result: [Stuff]? = nil
// load operation
expectation.fulfill()
completion(result)
}
self.waitForExpectations(timeout: 90) { (error: Error?) in
XCTAssert((error == nil), error?.localizedDescription ?? "load - failed with unknown error")
}
}
}
ПРИМЕЧАНИЕ. Существует два подхода к ожиданиям: первое ожидание сохраняется в переменной, поэтому при необходимости оно может быть выполнено из другой функции, другое создается локально в теле функции и выполняется из замыкания.