Как написать модульный тест для `downloadTask` с` завершением Handler `?
Вот моя функция загрузки:
// Download a file from the url to the local directory
class func downloadUrl(url: URL, to dirUrl: URL, completion: (() -> ())?){
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url: url)
let task = session.downloadTask(with: request) {(tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success, copy the downloaded file from the memory to the disk
print("Finished downloading!")
do {
try FileManager.default.copyItem(at: tempLocalUrl,to:
dirUrl.appendingPathComponent((response?.suggestedFilename)!))
if completion != nil {
completion!()
}
} catch (let writeError) {
print("Fliled to write file \(dirUrl) : \(writeError)")
}
} else {
print("Failure: \(String(describing: error?.localizedDescription))")
}
}
task.resume()
}
Я хочу написать метод модульного теста, чтобы проверить, загружает ли он файл с url
к dirUrl
,
func testDownloadUrl(){
let fm = FileManager.default
let url = URL(string: "https://raw.githubusercontent.com/apple/swift/master/README.md")
fileDownloader.downloadUrl(url: url!, to: fm.temporaryDirectory, completion: nil)
// Check the contents of temp file
let tempContents = try? fm.contentsOfDirectory(atPath: fm.temporaryDirectory.path)
print("Contents: \(tempContents)")
}
Тем не менее, не было никакого вывода "Закончена загрузка!" или "Сбой...", хотя я прошел модульное тестирование, поэтому я думаю, что в этом тесте не было вызвано завершение.
У меня вопрос, как заставить метод модульного теста ждать, пока задача загрузки не будет завершена?
1 ответ
Стандартная идиома заключается в использовании API асинхронного тестирования XCode, в основном XCTestExpectation
учебный класс. Они доступны начиная с Xcode 6, поэтому, если вы используете последнюю версию, вы должны быть покрыты;)
Общий шаблон асинхронного теста выглядит следующим образом:
func testAsyncFunction() {
let asyncDone = expectation(description: "Async function")
...
someAsyncFunction(...) {
...
asyncDone.fulfill()
}
wait(for: [asyncDone], timeout: 10)
/* Test the results here */
}
Это заблокирует выполнение теста до тех пор, пока вышеупомянутая функция не завершится (или не истечет указанное время ожидания).