2016-03-26 10 views
6

I m scrivere un Uni-test per un metodo di login con una chiamata HTTP.post, come:angular2 - come simulare errore sul test di unità http.post

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.") 
    ); 

Il problema è che io non sono in grado di simulare il ramo di errore; ogni volta viene chiamato il metodo onLoginComplete;

qui è la mia prova:

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

})); 

Grazie ancora a tutti.

risposta

18

Prima di tutto bisogna sostituire la classe XHRBackend dal MockBackend uno:

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

    (...) 
}); 

noti che HttpService è il servizio che utilizza l'oggetto Http e voglio provare.

Quindi è necessario iniettare il mockBackend e iscriversi sulla sua proprietà connections. Quando viene inviata una richiesta, viene richiamata la richiamata corrispondente ed è possibile specificare gli elementi di risposta come il corpo. Il servizio riceverà questa risposta come risposta della chiamata. Quindi sarai in grado di testare il tuo metodo di servizio basato su questo.

Qui di seguito descrivo come testare il metodo getItems del HttpService:

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

Ecco il codice di getItems metodo della HttpService:

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

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

Per simulare un errore è sufficiente utilizzare il mockError metodo invece del uno:

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

piccola domanda: Come si dovrebbe aggiungere un errore codice di stato http (404, 422, 500, ecc.) con mockError, oltre alla stringa? Nel mio caso, alcune risposte del server non restituiranno altro che quello. Per qualche motivo non ho trovato un esempio che lo mostri ovunque. –

+1

@LucioMollinedo perché non è supportato nell'attuale RC. Vedere https://github.com/angular/angular/pull/8961 per la correzione di bug per renderlo disponibile. Nel frattempo, i test di unità scadenti dovranno subire un altro colpo. – Fiddles

+0

Mi chiedo se questa soluzione possa essere applicata alla versione corrente di angular (2.4)? Ho provato ad adattarlo qui: http://stackoverflow.com/questions/42192911/ senza risultato ... Qualcuno può consigliare per favore? – balteo

2

È possibile simulare un errore come questo:

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

ho creato una piccola classe

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

che può utilizzare come questo

connection.mockError(new MockError(404));