2017-12-21 23 views
1

私はhttp.get/post/etcの応答をユニットテストしようとしています。 角度5ユニットのHTTP応答のテスト

は、私は非常に便利だった。このチュートリアルが見つかりました: https://medium.com/spektrakel-blog/angular-testing-snippets-httpclient-d1dc2f035eb8

を経由して、それを次のように、私は私のユニットテストを構成していると私は作業のすべてを取得することができるんだけど、私はそれがある持っている一つの部分がありますチュートリアル...チュートリアルで

と矛盾し、それがこのようなサービスのログイン機能をテストするために示しています:ここ

it(`should emit 'true' for 200 Ok`, async(inject([HttpClientFeatureService, HttpTestingController], 
    (service: HttpClientFeatureService, backend: HttpTestingController) => { 
     service.login('foo', 'bar').subscribe((next) => { 
     expect(next).toBeTruthy(); 
     }); 

     backend.expectOne('auth/login').flush(null, { status: 200, statusText: 'Ok' }); 
    }))); 

れ、テストされているサービス上の実際の方法があります10

login(user: string, password: string): Observable<boolean> { 
    const body = new HttpParams() 
     .set(`user`, user) 
     .set(`password`, password); 
    const headers = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }); 

    return this.http.post(`auth/login`, body.toString(), { headers, observe: 'response' }) 
     .map((res: HttpResponse<Object>) => res.ok) 
     .catch((err: any) => Observable.of(false)); 
    } 

ここに私のログイン機能です:

login(username: string, password: string): Observable<any> { 
    this.loggingService.log('LoginService | login | username: ' + username + '; password: xxxxx'); 

    return this.http.post(this.loginUrl, { username: username, password: password }) 
     .map((response: any) => { 
      console.log('response: ' + JSON.stringify(response)); 

      if (response && response.length > 0) { 
       return response; 
      } else { 
       return this.parseErrorResponse(response); 
      } 
     }); 
} 

そして、ここでは私のユニットテストです:

it('login should return a valid JWT', async(inject([LoginService, HttpTestingController], (service: LoginService, backend: HttpTestingController) => { 
    service.login('user', 'password').subscribe((next) => { 
     expect(next).toEqual('asdfasdfasdf'); 
    }); 

    backend.expectOne(environment.authenticationServiceBaseUrl + 'api/login') 
     .flush('asdfasdfasdf', { status: 200, statusText: 'Ok' }); 
}))); 

あなたがここでの違いは、マップ応答セクションにあるわかります。私のバージョンは単体テストのhttp.post呼び出しから単なる文字列を取り戻していますが、例ではHttpResponseオブジェクトを返すことを示しており、statusTextプロパティが「OK」と等しいことを確認しています。

私のバージョンは実際のHttpResponse(statusとstatusTextを含む)を返しているのに対し、なぜ文字列を返すのですか?私はここにチュートリアルバージョンを望んでいます...

この例では、応答の本体に nullを返しますが、私はそこにダミーのJWT値を追加してテストを受けなければなりませんパス。 nullをテストのように指定しても、ユニットテストで得られる応答は nullです。

ここで私は間違っていますか?

+1

このチュートリアルでは、 'observe: 'response''を使用しています。つまり、返されたobservableによって生成されたイベントは、ボディだけでなくレスポンスです。これはhttpチュートリアルでカバーされています。しかし、私はテストを作成する方法を理解していません。バックエンドが実際に返すものに基づいて、コードとテストを作成する必要があります。したがって、成功した場合にバックエンドがJWTトークンを文字列として返し、失敗した場合にエラー応答を返すと、テストでステータスコードをテストすることは無意味です:あなたのコードはステータスを使用しません何をすべきかを決めるコード。 –

+0

Gotcha、私のAPIサービスはまだ開発されていないので、どのような対応が必要かを判断しています。 – ganders

+1

典型的な認証サービスはJSON本体を含む200または201応答を返します成功の場合には、トークン(ただし、ログインしているユーザーに関する他の情報も含む)を含んでいます。そして、失敗の場合の401の応答 –

答えて

1

このチュートリアルでは、observe: 'response'を使用しています。つまり、返されたオブザーバブルによって生成されるイベントは、ボディだけでなくレスポンスです。

これはthe http guideでカバーされています。

関連する問題