2016-03-26 6 views
6

Ich bin einen Uni-Test für eine Login-Methode mit einem HTTP.post Aufruf zu schreiben, wie:angular2 - wie Fehler auf http.post Unit-Test zu simulieren

this.http.post(endpoint, creds, { headers: headers}) 
     .map(res => res.json()) 
     .subscribe(
     data => this.onLoginComplete(data.access_token, credentials), 
     err => this.onHttpLoginFailed(err), 
     () => this.trace.debug(this.componentName, "Login completed.") 
    ); 

Das Problem ist, dass ich nicht bin fähig, den Fehlerzweig zu simulieren; Jedes Mal wird die onLoginComplete-Methode aufgerufen.

hier ist mein Test:

it("check that Atfer Login, console show an error ", inject(
    [TraceService, Http, MockBackend, WsiEndpointService], 
    (traceService: TraceService, http: Http, 
    backend: MockBackend, wsiEndpoint: WsiEndpointService) => { 

    let tokenTest: number = 404 ; 

    let response: ResponseOptions = null {} // i think i have to modify this 

    let connection: any; 

    backend.connections.subscribe((c: any) => connection = c); 

    let authService: AuthService = new AuthService(http, Service1, Service2); 

    authenticationservice.login({ "username": "a", "password": "1" }); 

    connection.mockRespond(new Response(response)); 

    expect(ERROR); 

})); 

Nochmals vielen Dank an alle.

Antwort

18

Zuerst müssen Sie die XHRBackend Klasse durch die MockBackend ein außer Kraft zu setzen:

describe('HttpService Tests',() => { 
    beforeEachProviders(() => { 
    return [ 
     HTTP_PROVIDERS, 
     provide(XHRBackend, { useClass: MockBackend }), 
     HttpService 
    ]; 
    }); 

    (...) 
}); 

Beachten Sie, dass HttpService ist der Dienst, der die Http Objekt verwendet, und ich möchte testen.

Dann müssen Sie die mockBackend injizieren und unter seiner connections Eigenschaft abonnieren. Wenn eine Anfrage gesendet wird, wird der entsprechende Callback aufgerufen und Sie können die Response-Elemente wie den Body angeben. Der Dienst empfängt diese Antwort als Antwort des Anrufs. Auf diese Weise können Sie Ihre Service-Methode testen.

Im Folgenden werde ich beschreiben, wie die getItems Methode des HttpService testen:

it('Should return a list of items', inject([XHRBackend, HttpService, Injector], (mockBackend, httpService, injector) => { 
    mockBackend.connections.subscribe(
    (connection: MockConnection) => { 
     connection.mockRespond(new Response(
     new ResponseOptions({ 
      body: [ { id: '1', label: 'item1' }] 
     }))); 
     }); 

    httpService.getItems().subscribe(
    items => { 
     expect(items).toEqual([ { id: '1', label: 'item1' }]); 
    }); 
    }); 
}); 

Hier ist der Code von getItems Methode des HttpService:

@Injectable() 
export class HttpService { 
    constructor(private http:Http) { 
    } 

    getItems(): Observable<any[]> { 
    return this.http.get('/items').map(res => res.json()); 
    } 
} 

ein Fehler einfach zu simulieren die mockError verwenden Verfahren anstelle des mockResponse eins:

mockBackend.connections.subscribe(
    (connection: MockConnection) => { 
     connection.mockError(new Error('some error')); 
    }); 
+11

Kleine Frage verwenden können: Wie würden Sie einen Fehler hinzufügen http Statuscode (404, 422, 500, etc) mit MockError, neben der Zeichenfolge? In meinem Fall werden einige Serverantworten nichts zurückgeben. Aus irgendeinem Grund habe ich kein Beispiel gefunden, das das irgendwo zeigt. –

+1

@LucioMollinedo, weil es in der aktuellen RC nicht unterstützt wird. Siehe https://github.com/angular/angular/pull/8961 für den Bugfix, um dies zur Verfügung zu stellen. In der Zwischenzeit müssen schlechte Unit-Tests einen weiteren Schlag bekommen. – Fiddles

+0

Ich frage mich, ob diese Lösung auf die aktuelle Version von angular (2.4) angewendet werden kann? Ich habe versucht, es hier anzupassen: http://stackoverflow.com/questions/42192911/ ohne Erfolg ... Kann jemand bitte beraten? – balteo

2

Sie können einen Fehler wie diese simulieren:

connection.mockError(new Response(new ResponseOptions({ 
    body: '', 
    status: 404, 
}))); 

I

import {ResponseOptions, Response} from '@angular/http'; 

export class MockError extends Response implements Error { 

    name: any; 
    message: any; 

    constructor(status: number, body: string = '') { 
     super(new ResponseOptions({status, body})); 
    } 
} 

eine kleine Klasse geschaffen, die wie diese

connection.mockError(new MockError(404));