Search code examples
angularerror-handlingxmlhttprequestkarma-jasmineobservable

Angular2 error being processed through map, not catch


I'm writing an Angular2 program. It fetches a list of "states" (like NY, NJ, OH, WY, etc.) and shows them on a form. Good enough. Now for the test suite in Karma.

I have the fake OptionService testing OK, but now want to test the error handling.

Using the same beforeEach() as is used for the successful async fetch I have this exception handling test:

it('getOptions() should throw an exception',
  async(inject([OptionService], (optionService: OptionService) => {
    mockBackend.connections.subscribe(
      (connection: MockConnection) => {
        connection.mockRespond(new Response(new ResponseOptions(
          // Option 1:
        { body: [], status: 404 }         

          // Option 2:
          //Observable.throw('Error from mock Http call for getOptions')
        )));
      });

    optionService.getOptions()
      .subscribe(
        options => {
          expect(options.length).toBe(1);
          expect(options[0].id = 'NJ');
          expect(options[0].name = 'New Jersey');
          expect(options[0].topic = Option.TOPIC_STATE);
        },
        error => { expect(error == 'Error from mock Http call for getOptions') }
      );
  })
));

When using Option 1 or Option 2 (see code) I have the same result. The first function of subscribe() gets the result and the second function -- the supposed error handler -- doesn't get called.

When executing Option 1 the (options.length = 0) and since there is no options[0] the expect() complains. It just shouldn't be executing at all, by my understanding.

When executing Option 2 the (options = undefined) and I get much the same errors (" 'undefined' has no 'id' property ").

So my questions:

  1. If the http get() fails, will it return a good JSON object or throw something? Perhaps I'm not expecting the correct data.

  2. Shouldn't the error function (second parameter of .subscribe()) be called? What must I change to make it occur for me?

Thanks,

Jerome.

UPDATE on 2/10/17: Alex's answer is correct. I want to share something I learned about preparing mocked data.

In testing the OptionService I prepared mock data:

connection.mockRespond(new Response(
  new ResponseOptions({
      body: [ { id: 'NJ', name: 'New Jersey', topic: Option.TOPIC_STATE } ] 
  )));

This yields the error:

ERROR: 'Error from mock Http call for getOptions'

The data that doesn't yield the error is:

connection.mockRespond(new Response(
  new ResponseOptions({
      body: { data: [ { id: 'NJ', name: 'New Jersey', topic: Option.TOPIC_STATE } ] }
  )));

Solution

  • You just need to use connection.mockError(yourError).

    UPDATE.

    Answers to your particular questions.

    1) Since angular http service operates through Observables it uses their mechanics to deliver results: successful results will go to onNext() handler in subscribe() while erroneous ones will go to onError() handler. Looking at your code I'd say that in general your expectations of how it should work are correct except for particular values - they may be different from what you expect but at least they will go to right places and they will contain something similar to what you expect.

    2) Yes, it should. What you have to change is above in this answer.