2016-11-08 8 views
1

私はAngular 2サービスで特定のユーザーアカウント(ログインしているユーザーアカウント)の詳細をすべて取得し、Observableを返します。角度2 Observable and Promiseコールバックユニットテスト

(私はそれが価値があるもののために、認証のためにAngularFire2を使用しています)

あなたが見ることができるように、getData方法は、今度は、(観測可能として)認証状態を返すgetAuth方法を使用していますgetTokenメソッド(Promiseを返す)によって使用され、Authorizationヘッダーにデータを埋め込み、http要求を行うために使用されるトークンを取得します。 (私は私のコードをリファクタリングを必要とするかもしれないことを理解しない、と私はその上の任意のフィードバックをいただければ幸いです)

getData(): Observable<IData> { 
    let authHeaders = new Headers(); 

    return Observable.create((o: Observer<IData>) => { 
     this.getAuth().subscribe((authState: IState) => { 
      this.getToken(authState).then(token => { 
       /* ... 
       * Do things with that token, call an http service etc. 
       */ ... 
       authHeaders.set('Authorization', token); 

       this.http.get('myendpoint/', { 
        headers: this.authHeaders 
       }) 
       .map((response: Response) => response.json()) 
       .map((data: IData) => { 
        o.next(data); 
       }); 
      }) 
      .catch((error: Error) => { 
       Observable.throw(new Error(`Error: ${error}`)); 
      }); 
     }); 
    }); 
} 

私はユニットテストに新しいですが、このメソッドをテストしようとしているが、私はまだカバーすることはできませんその方法の中のPromiseの.catch。私は拒否し、私の観測可能かどうかを確認するためのテストがスローされます私は何とかgetTokenからその約束をしなければならない理解して何から

describe('Service: UserDataService',() => { 
    let mockHttp: Http; 
    let service: UserDataService; 
    let getAuthSpy: jasmine.Spy; 
    let getTokenSpy: jasmine.Spy; 

    beforeEach(() => { 
     mockHttp = { get: null } as Http; 

     TestBed.configureTestingModule({ 
      providers: [ 
       { provide: Http, useValue: mockHttp }, 
       AngularFire, 
       UserDataService, 
      ] 
     }); 

     service = new UserDataService(AngularFire, mockHttp); 

     spyOn(mockHttp, 'get').and.returnValue(Observable.of({ 
      json:() => { 
       "nickname": "MockNickname" 
      } 
     })); 

     getAuthSpy = spyOn(service, 'getAuth').and.returnValue(Observable.of({ 
      "auth": { 
      "uid": "12345" 
     })); 

     getTokenSpy = spyOn(service, 'getToken').and.returnValue(new Promise((resolve, reject) => { 
      resolve('test promise response'); 
     })); 
    }); 

    describe('getLead',() => { 
     beforeEach(() => { 
      spyOn(service, 'getLead').and.callThrough(); 
     }); 

     it('should return an object of user data and set the dataStore.userEmail if state exists',() => { 
      service.getLead().subscribe(res => { 
       expect(res).toEqual(jasmine.objectContaining({ 
        nickname: 'MockNickname' 
       })); 
      }); 

      expect(service.getLead).toHaveBeenCalled(); 
     }); 

     it('should throw, if no authState is provided',() => { 
      getAuthSpy.and.returnValue(Observable.of(false)); 

      service.getLead(); 

      expect(service.getLead).toThrow(); 
     }); 

     it('should throw, if getToken() fails to return a token',() => { 
      getTokenSpy.and.returnValue(new Promise((resolve, reject) => { 
       reject('test error response'); 
      })); 

      /* 
      * This is where I am getting lost 
      */ 

      service.getLead(); 

      expect(service.getLead).toThrow(); 
     }); 
    }); 
}); 

:ここ

は私のユニットテストは次のようになります。

大変助かりましたか?

+0

spyOn(...)and.returnValue(Observable.throw(...)toPromise()) '? 'Observable.map'ではこれをもう少し線形にすることができます。必要に応じて' fromPromise'と 'toPromise'を変換してネストを増やすのではなく、段階的に進むことができます。 – jonrsharpe

答えて

1

jasmineとAngularFire2のどちらも使用しないので、正確に何をしなければならないのかはわかりませんが、コードからはthis.getToken(authState)Promiseを返します。

質問はどのライブラリからこのPromiseクラスが由来しているか(あなたが使用しているpolyfillと言います)。私の知る限りPromises/Aの実装は試してみるとコールバックコールをラップする必要があります知っているよう

- キャッチし、そうthen(...)であなたのコールバックは、約束がcatch()に伝播するという例外をスローした場合。だから私はresponse.json()でエラーを引き起こすいくつかの不正な形式のJSONでthis.http.get('myendpoint/')からの偽の応答をすることができたと思います。

.catch((error: Error) => { 
    Observable.throw(new Error(`Error: ${error}`)); 
}); 

これは文字通り何もしません:

第二のものは、catch()のためのインナーコールバックです。返信文はありません。Observable.throw()は、Observableチェーン内で何かを行う必要があります。この.catch()メソッドは、Promiseクラスのものであり、Observableのものではありません。

あなたはそれが実際にオブザーバーにエラーを伝播したい場合は、あなたが明示的に呼び出す必要があり:

.catch((error: Error) => { 
    o.error(error); 
}); 

エラーは、それが同様に観察者に渡されるObservable.create()まで泡立てたぶんあれば、私は」これについてはわかりません。

0

私はその後、私はObservable.fromを使用しました、私同様の問題があった:

spyOn(service, 'function').and.returnValue(Observable.fromPromise(Promise.reject({}))); 

あなたは約束の内部でエラーを返します。拒否