简体   繁体   中英

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.

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 mockResponse one:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM