如何使用 `completionHandler` 为`downloadTask` 编写单元测试?
Posted
技术标签:
【中文标题】如何使用 `completionHandler` 为`downloadTask` 编写单元测试?【英文标题】:How to write unit test for `downloadTask` with `completionHandler `? 【发布时间】:2017-11-05 20:00:41 【问题描述】:这是我的下载功能:
// 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)")
但是,没有输出“下载完成!”或者“失败...”,即使我通过了单元测试,所以我猜在这个测试用例中没有调用completionHandler。
我的问题是如何让单元测试方法等到下载任务完成?
【问题讨论】:
【参考方案1】:标准习惯用法是使用Xcode asynchronous testing APIs,主要是XCTestExpectation
类。这些从 Xcode 6 开始就可用,因此,如果您使用的是最新版本,则应该包括在内;)
一般的异步测试模板如下:
func testAsyncFunction()
let asyncDone = expectation(description: "Async function")
...
someAsyncFunction(...)
...
asyncDone.fulfill()
wait(for: [asyncDone], timeout: 10)
/* Test the results here */
这将阻止您的测试执行,直到上述功能完成(或指定的超时已经过去)。
【讨论】:
以上是关于如何使用 `completionHandler` 为`downloadTask` 编写单元测试?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Swifts DispatchQueue() 和 completionHandlers 组织网络登录?
作为命令行工具运行时,如何让 NSURLSession 处理 completionHandler
UIActivityViewController completionHandler 如何检查活动是不是发送成功?