2017-11-05 1 views
2

は、ここに私のダウンロード機能である:`completionHandler`で `downloadTask`の単体テストを書く方法は?

// 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() 
} 

私はそれがdirUrlからurlからファイルをダウンロードするかどうかをテストするユニットテストメソッドを書きたいです。

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)") 
    } 

ただし、出力がありませんでした。「ダウンロード済みです!」私が単体テストに合格したにもかかわらず、 "失敗..."というように、このテストケースでは完了ハンドラが呼び出されなかったと思います。

私の質問は、ダウンロードタスクが完了するまでユニットテストメソッドを待機させる方法です。

答えて

3

標準的なイディオムは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 */ 
} 

この意志ブロックテストの実行前述の関数が完了するまで(または)、指定されたタイムアウトが経過しています。

関連する問題