2017-10-12 8 views
0

私はサービスを使用してHttpClientを使用しています。サーバーが応答してエラーが発生した場合は、POSTリクエストを使用してメッセージをフォーマットして再スローします。私はこのシナリオをテストしようとしましたが、テストを模擬しませんでした。 HttpTestingControllerは戻って私のカスタムエラーメッセージを送信していないにもそれがサービスでそれをキャッチして、それを再投げ、適切な方法は、この角度のテスト4 catchと_throwエラーロジックを持つHttpTestingController

サービスコード行うにいただきました:

login(credentials: LoginPayload): Observable<LoginSuccessPayload> { 

     return this.http.post<LoginSuccessPayload>('/api/auth/signin', credentials) 
      .map(res => {authUser: res.user}) 
      .catch((error: HttpErrorResponse) => { 
       if (error.message) { 
        return _throw(error); 
       } 
       return _throw({message: 'Notification.LoginError'}); 
      }); 

} 

今テスト

beforeEach(() => { 
    TestBed.configureTestingModule({ 
     imports: [HttpClientTestingModule], 
     providers: [AuthService] 
    }); 

    authService = TestBed.get(AuthService); 
    httpMock = TestBed.get(HttpTestingController); 
}); 

it('should format the error message', (done) => { 
    const credentials = {userName: 'bob', password: '123'} as LoginPayload; 
    const mockErrorResponse = {message: 'failed to login'} ; 

    authService.login(credentials).subscribe(() => {}, err => { 
     expect(err.message).toEqual(mockErrorResponse.message); 
     done(); 
    }); 

    const req = httpMock.expectOne('/api/auth/signin'); 
    req.error(new ErrorEvent(mockErrorResponse.message)); 

    httpMock.verify(); 
}); 

答えて

0

私にはうまくいくいくつかの提案があります。これで

authService = TestBed.get(AuthService); 
httpMock = TestBed.get(HttpTestingController); 

:私はこの置き換えたいそもそも

const testBed = getTestBed(); 
authService = testBed.get(AuthService); 
httpMock = testBed.get(HttpTestingController); 

を私はここでのポイントは、あなたが実際にテストベッドへのアクセスに失敗するということだと思います。

私はまた、広告リクエストには、次のとPOSTリクエストで検証したい:

expect(req.request.method).toBe("POST"); 

はこれらは私が最初に考えた上で追加することになりますものです。

1

私はこれに遅れていることを知っていますが、私はこのように私がそうしたように誰かのためにこれに答えると思っていました。私は、このエラーのケースのまわりでangular.ioの完全なlack of documentationが狂っているのを見つける。 "それはあなた自身を描く"と思いますか?

とにかく...私が取ったアプローチは、.flush()を使用してドキュメントが、それは成功と失敗した応答の両方のために使用することができるstateないほど簡単であるように思わなかったので完全に.error()を避けるためでした。ここで

は、私はフラッシュを使用するようにコードを更新してしまう方法は、次のとおりです。

it('should format the error message', (done) => { 
    const credentials = {userName: 'bob', password: '123'} as LoginPayload; 
    const mockErrorResponse = {message: 'failed to login'} ; 

    authService.login(credentials).subscribe(() => {}, err => { 
     // NOTE: err.error.message 
     expect(err.error.message).toEqual(mockErrorResponse.message); 
     done(); 
    }); 

    const req = httpMock.expectOne('/api/auth/signin'); 
    req.flush({message: mockErrorResponse.message}, {status: 400, statusText: ''}); 

    httpMock.verify(); 
}); 

@angular/httpHttpとは対照的に、@angular/common/httpHttpClientでこの更新プログラムに関する1つの迷惑な部分は、エラーメッセージが今err.errorの財産であるということですerrではなく、subscribe()にあります。

あなたが私のようで、1つのバージョンから別のバージョンにアップグレードする場合は、err.messageへの参照をすべてerr.error.messageに更新する必要があります。私はこれが役立つことを願っています

+0

私はあなたのソリューションが好きで、それも私のために働く。しかし、あなたのコード内のflush()は、サブスクライバにエラーを返します。あなたはエラーをエミュレートするreq.error()を呼び出すはずですか? –

+0

@YakovFainステータスコードなどのプロパティを持つオブジェクトを含む.flush()の第2引数。 –

+0

ステータス200でflush()を試みましたが、それでもサブスクライバのエラーハンドラに行きます。これは私にとってはうまくいく: '' 'req.error(新しいErrorEvent( 'エラーテキスト')); ... .subscribe(()=> {}、 errorResponse => expect(errorResponse.error.type)。toEqual( 'エラーテキスト') ); '' ' –

関連する問題