Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular2 - how to simulate error on http.post unit test

I m writing a Uni-test for a login Method with an HTTP.post call, like:

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

The problem is that i'm not able to simulate the error branch; everytime is called the onLoginComplete Method;

here is my 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);

}));

Thanks again to everyone.

like image 568
AntuJitsu Avatar asked Mar 26 '16 16:03

AntuJitsu


2 Answers

First you need to override the XHRBackend class by the MockBackend one:

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

  (...)
});

Notice that HttpService is the service that uses the Http object and I want to test.

Then you need to inject the mockBackend and subscribe on its connections property. When a request is sent, the corresponding callback is called and you can specify the response elements like the body. The service will receive this response as the response of the call. So you'll be able to test your service method based on this.

Below I describe how to test the getItems method of the 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' }]);
    });
  });
});

Here is the code of getItems method of the HttpService:

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

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

To simulate an error simply use the mockError method instead of the mockResponseone:

  mockBackend.connections.subscribe(
    (connection: MockConnection) => {
      connection.mockError(new Error('some error'));
    });
like image 130
Thierry Templier Avatar answered Nov 14 '22 21:11

Thierry Templier


You can simulate an error like this:

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

I created a small class

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

which can use like this

connection.mockError(new MockError(404));
like image 27
tschuege Avatar answered Nov 14 '22 20:11

tschuege