2017-08-02 7 views
2

ユニットテストでURLSessionsやUserDefaultsなどのOSオブジェクトへの依存関係を削除しようとしています。テスト目的で作成した疑似UserDefaultsオブジェクトにプリキャッシュデータをモックしようとしています。ユニットテストのオブジェクトUserDefaultsオブジェクトを返す_ArrayBuffer

私は、エンコードとデコードの機能を持つテストクラスを作成し、モックデータをメンバ変数[String:AnyObject]辞書に格納しました。私のアプリでは、起動時にキャッシュのデータをチェックし、見つかった場合はネットワークコールをスキップします。

私が得ることができましたすべてがゼロ年代またはこのいずれかの永続的エラーです:

fatal error: NSArray element failed to match the Swift Array Element type

は、デバッガを見てみると、デコーダは、カスタムタイプ「質問」の配列を返す必要があります。代わりに_ArrayBufferオブジェクトを取得します。

私のアプリが自分のモックuserdefaultsオブジェクトにデータを読み込んでも正常に動作しますが、オブジェクトをハードコードするとこのエラーが発生します。

class MockUserSettings: DataArchive { 
    private var archive: [String: AnyObject] = [:] 

    func decode<T>(key: String, returnClass: T.Type, callback: (([T]?) -> Void)) { 
     print("attempting payload from mockusersettings with key: \(key)") 
     if let data = archive[key] { 
      callback(data as! [T]) 
     } else { 
      print("Found nothing for: \(key)") 
      callback(nil) 
     } 
    } 

    public func encode<T>(key: String, payload: [T]) { 
     print("Adding payload to mockusersettings with key: \(key)") 
     archive[key] = payload as AnyObject 
    } 
} 

と私は合格しようとしているテスト:

func testInitStorageWithCachedQuestions() { 
    let expect = XCTestExpectation(description: "After init with cached questions, initStorage() should return a cached question.") 

    let mockUserSettings = MockUserSettings() 
    var questionsArray: [Question] = [] 
    for mockQuestion in mockResponse { 
     if let question = Question(fromDict: mockQuestion) { 
      questionsArray.append(question) 
     } 
    } 
    mockUserSettings.encode(key: "questions", payload: questionsArray) 
    mockUserSettings.encode(key: "currentIndex", payload: [0]) 
    mockUserSettings.encode(key: "nextFetchDate", payload: [Date.init().addingTimeInterval(+60)]) 

    let questionStore = QuestionStore(dateGenerator: Date.init, userSettings: mockUserSettings) 

    questionStore.initStore() { (question) in 
     let mockQuestionOne = Question(fromDict: self.mockResponse[0]) 
     XCTAssertTrue(question == mockQuestionOne) 
     XCTAssert(self.numberOfNetworkCalls == 0) 
     expect.fulfill() 
    } 
    wait(for: [expect], timeout: 1.0) 
} 

誰かが私は「何のまわりで私の頭をラップ私を助けることができればここで

はモックUserDefaultsのための私のコードがオブジェクトであります間違っていると大いに感謝しています。モックオブジェクトを正しく保管していますか?このArrayBufferとArrayBridgeStorageは何ですか?

答えて

0

私は私の問題を解決しました。私のカスタムクラスは、私のアプリとテストの両方を対象としていました。単体テストでは、私の主なアプリの代わりに私のクラスのコンストラクタのテストターゲットのバージョンを使用していました。

だから、この教訓は、@testable importを使用しているだけで、あなたのアプリクラスはテストを対象としていません。

関連する問題