2017-12-21 10 views
1

Ich versuche zu Unit-Test meine http.get/post/etc Antworten.Angular 5-Unit-Test HTTP-Antwort

ich dieses Tutorial gefunden, die sehr hilfreich war: https://medium.com/spektrakel-blog/angular-testing-snippets-httpclient-d1dc2f035eb8

Wenn man durch und folgt, habe ich meine Unit-Tests konfiguriert und ich bin in der Lage, alles bekommen arbeiten, aber es ist ein Teil, das ich habe, dass ist mit dem Tutorial inkonsequent ...

im Tutorial zeigt es die Service Login-Funktion wie folgt zu testen:

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' }); 
    }))); 

Und hier ist die eigentliche Methode auf dem Dienst, getestet wird:

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

Hier ist meine Login-Funktion:

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

Und hier ist meine Unit-Test:

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' }); 
}))); 

Sie den Unterschied bemerken werden, ist hier in der Karte Antwortabschnitt. Meine Version erhält nur eine Zeichenfolge aus dem Aufruf http.post des Komponententests zurück, während das Beispiel zeigt, dass es ein HttpResponse-Objekt zurückgibt und nur überprüft, ob die Eigenschaft statusText gleich 'Ok' ist.

Warum gibt meine Version nur die Zeichenfolge zurück, während die Beispielversion die tatsächliche HttpResponse (die Status und StatusText enthält) zurückgibt? Ich WÜNSCHE die Tutorial-Version hier ...

Das Beispiel zeigt, dass es null im Körper der Antwort über den Flush-Funktionsaufruf zurückgibt, während ich meinen Dummy-JWT-Wert dort hinzufügen musste, um meinen Test zu bekommen bestehen. Selbst wenn ich das als null angaben, um wie der Test zu sein, dann ist die Antwort, die ich im Komponententest bekomme, null.

Wohin gehe ich hier falsch?

+1

Das Lernprogramm verwendet 'beobacht: 'Antwort'', was bedeutet, dass Ereignisse, die von der zurückgegebenen Observablen ausgegeben werden, Antworten sind und nicht nur der Körper. Dies wird im http-Lernprogramm behandelt. Aber ich verstehe nicht, wie Sie Ihren Test erstellen: Sie sollten den Code und den Test basierend darauf, was Ihr Backend eigentlich zurückgeben soll, kritisieren. Wenn also das Backend im Erfolgsfall ein JWT-Token als String im Body zurückgeben soll und im Fehlerfall eine Fehlerreaktion, dann ist das Testen des Statuscodes in Ihrem Test nutzlos: Ihr Code verwendet den Status nicht Code, um zu entscheiden, was zu tun ist. –

+0

Gotcha, mein API-Dienst ist noch nicht entwickelt, so in gewisser Weise bin ich bestimmt, was die Antwort sein sollte ... – ganders

+1

Ein typischer Authentifizierungsdienst würde eine 200 oder 201 Antwort, enthält einen JSON-Körper (nicht nur Strings zurücksenden), die das Token enthalten (aber vielleicht auch andere Informationen über den angemeldeten Benutzer), falls Erfolg eintritt. Und eine 401 Antwort im Falle des Scheiterns –

Antwort

1

Das Lernprogramm verwendet observe: 'response', was bedeutet, dass Ereignisse, die von der zurückgegebenen Observablen ausgegeben werden, Antworten sind und nicht nur der Körper.

Dies ist in the http guide abgedeckt.