2017-02-16 19 views
1

test()メソッドを実行する前に複数の呼び出しを行う必要があります。完成ブロックがあり、私はwaitForExpectations()を使用しています。複数の非同期呼び出しがあるので、私はカウンタを使用しています。 expectation.fulfill()は、カウンタがコール数に達した場合にのみ発生します。XCTestCaseのsetUp()で複数の非同期呼び出しを待機する

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()は複数の非同期呼び出しを返すのを待つことができますか?

+0

あなたはハンドラを実装し、起こりうるエラーをチェックしようとしましたか? – user3581248

答えて

1

私は同様の場合がありました。私がやった解決策は、私の前提条件に対する期待を追加し、期待値のタイムアウトを合理的な値に設定するいくつかの関数を呼び出すことでした。期待の完了ハンドラで私はセットアップアルゴリズムの次のステップをトリガした。すべての予備的なステップが合格したら、私は実際のテストロジックを開始します。

Appleドキュメントにlinkを添付してください。

EDIT:以下のコード例を参照してください。

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

注:期待のための2つのアプローチがありますが、最初の期待が変数に保存されるので、必要であれば、それは別の関数から満たすことができます、もう1つは関数本体でローカルに作成され、クロージャから実行されます。