Заставить Alamofire сделать все на главной ветке? - PullRequest
0 голосов
/ 24 марта 2020

Есть ли способ заставить Alamofire выполнять всю свою работу в основном потоке? Это для тестового сценария, где мне нужно, чтобы основной поток не продолжал выполнение до тех пор, пока не завершатся сетевые вызовы, и я не узнаю статус. Тесты, о которых идет речь, использовались в рамках XCTest, поэтому я бы использовал XCTestExpectation для ожидания завершения. Среда, которую я использую, не работает с XCTest, поэтому мне нужно, чтобы Alamofire был синхронным.


Так как в первых двух комментариях предлагалось, как я должен тестировать, позвольте мне предоставить немного больше контекста.

У меня есть около 100 тестов, которые выполнялись просто отлично за последние 2 года. Тесты - это НЕ модульные тесты, а тесты пользовательского интерфейса с использованием Google EarlGrey 1. EarlGrey 1 предоставляет тестирование пользовательского интерфейса, которое выполняется под XCTest, так что вы можете комбинировать тестирование пользовательского интерфейса с проверкой состояния белого в приложении. Это здорово.

Эрл Грей 1 не поддерживает iOS 13, и поэтому я переношу тесты на EarlGrey 2, который работает поверх XCUITest. Что касается аспекта белого ящика, вы делаете удаленные вызовы из процесса тестирования в пакет, который внедряется в ваше приложение.

В этом случае «mock» - это сервер, но он выполняет сетевые вызовы, и это происходит когда я звоню в тестовую связку. Мне нужно знать, когда они заканчивают sh, чтобы я мог вернуться после того, как они закончили.

1 Ответ

1 голос
/ 24 марта 2020

Чтобы ответить на ваш вопрос: нет правильного способа заставить Alamofire выполнять вызовы в главном потоке, используя сам Alamorefire. Вообще говоря, вы можете заставить поток ждать результата, используя семафор. Alamofire, похоже, отвечает в главном потоке, что может привести к тупику.

Вы можете перевести нить в спящий режим до тех пор, пока не будет обработан обратный вызов:

var result: Data?
var done = false

// Do a call which will finish asynchonously
someCall(withBlock: { someResult in
    // Once done,
    result = someResult
    done = true
})

// Make the main thread wait
while(!done) {
    Thread.sleep(forTimeInterval: 0.1)
}

// This will be called after the block has been completed
print("\(result)")

То же самое может быть применительно к вызовам Alamofire, обратите внимание, что это может создать тупики с потоками, ожидающими друг друга.

Но чтобы помочь вам с вашей проблемой. В идеале вы не должны ждать выполнения сетевых вызовов в тестах по ряду причин, в том числе:

  • Тесты должны охватывать только одну часть функций, сетевые вызовы go сверх этого.
  • Включение сетевых вызовов означает, что внешние факторы, такие как отсутствие соединения inte rnet, будут влиять на результат теста, хотя в нем мало говорится о том, что ваш код работает должным образом.

Обычный подход заключается в том, чтобы «макетировать» 'части, которые должны рассматриваться как выходящие за рамки испытания. Вот пост о том, как это сделать для Alamofire .

...