Search code examples
unit-testingangularkarma-jasmine

Angular2, Jasmine-Karma, http Testing API Error{"isTrusted": true}


I have prepared a http test case for Angular2 app using jasmine-karma and getting an API error: Uncaught API Error

Use Case: I need test a http service for my Angular2 App using Karma-Jasmine and I am using the below method to achieve this.

But i am stuck at API error which is uncaught so please suggest me the solution or any alternate method to do a http service testing

Please suggest the solution, thanks in advance code follows:

Error:

Chrome 56.0.2924 (Mac OS X 10.12.3)
      "isTrusted": true
    }
    Error: API Error {
        at CatchSubscriber.selector (http://localhost:9877webpack:///src/app/services/api/api.service.ts:39:32 <- config/spec-bundle.js:15376:193) [ProxyZone]
        at CatchSubscriber.error (http://localhost:9877webpack:///~/rxjs/operator/catch.js:53:0 <- config/spec-bundle.js:43225:31) [ProxyZone]
        at MapSubscriber.Subscriber._error (http://localhost:9877webpack:///~/rxjs/Subscriber.js:128:0 <- config/spec-bundle.js:542:26) [ProxyZone]
        at MapSubscriber.Subscriber.error (http://localhost:9877webpack:///~/rxjs/Subscriber.js:102:0 <- config/spec-bundle.js:516:18) [ProxyZone]
        at XMLHttpRequest.onError (http://localhost:9877webpack:///~/@angular/http/src/backends/xhr_backend.js:95:0 <- config/spec-bundle.js:58151:34) [ProxyZone]
        at ProxyZoneSpec.onInvokeTask (http://localhost:9877webpack:///~/zone.js/dist/proxy.js:103:0 <- config/spec-bundle.js:66413:39) [ProxyZone]
        at ZoneDelegate.invokeTask (http://localhost:9877webpack:///~/zone.js/dist/zone.js:366:0 <- config/spec-bundle.js:66859:36) [ProxyZone]
        at Zone.runTask (http://localhost:9877webpack:///~/zone.js/dist/zone.js:166:0 <- config/spec-bundle.js:66659:47) [<root> => ProxyZone]
        at XMLHttpRequest.ZoneTask.invoke (http://localhost:9877webpack:///~/zone.js/dist/zone.js:420:0 <- config/spec-bundle.js:66913:38) [<root>]

Spec.ts file

import {Http,HttpModule,BaseRequestOptions,XHRBackend, Response, ResponseOptions} from '@angular/http';
import { MockBackend ,MockConnection} from '@angular/http/testing';
import { async, TestBed, inject,getTestBed } from '@angular/core/testing';
import {FactoryUsersApiService, User} from "../../../../services/api/factoryusers.api.service";
import {ApiService} from "../../../../services/api/api.service";

beforeEach(async(() => {
   TestBed.configureTestingModule({
     imports: [HttpModule],
    
    providers:[FactoryUsersApiService,ApiService,MockBackend]
       })
    .compileComponents();
  }));

describe('Build Home Component', () => {
   let subject: FactoryUsersApiService;
   let backend: MockBackend;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      providers: [       {
          provide: Http,
          useFactory: (mockBackend, defaultOptions) => {
            return new Http(mockBackend, defaultOptions);
          },
        }
      ]
    });
  }));

  beforeEach(async(inject([ApiService, MockBackend], (apiservice, mockBackend) => {
    subject = apiservice;
    backend = mockBackend;
  })));

it('should get Build Etl Report ', async(() => {
  let factoryUsersApiService: FactoryUsersApiService = getTestBed().get(FactoryUsersApiService);
  backend.connections.subscribe(
    (connection: MockConnection) => {
      connection.mockRespond(
        new Response(
          new ResponseOptions({
            body: {
              id: 200
            }
          }))
      );
    }
  );

  factoryUsersApiService.getBuildEtlReport("[email protected]").subscribe(
    (res) => {
      expect(res.id).toBe(200);  
    }
  );
}));
});


Solution

  • After all investigation through the chrome browser what i found is cross domain issue and i have fixed (cross domain check disabled) this with a COMMAND (in terminal)

    COMMAND: Run Chrome with cross domain check disabled: For OSX: /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-web-security --user-data-dir=ChromeUserData/

    And have minified the code as much as possible to the below:

    import {HttpModule} from '@angular/http';
    import {async, TestBed,getTestBed } from '@angular/core/testing';
    import {FactoryUsersApiService} from "../../../../services/api/factoryusers.api.service";
    import {ApiService} from "../../../../services/api/api.service";
    
    beforeEach(async(() => {
       TestBed.configureTestingModule({
         imports: [HttpModule],
         providers:[FactoryUsersApiService,ApiService]
           })
        .compileComponents();
      }));
    
    describe('Build Home Component:', () => {
    
      it('should get Current User(http server request)', async(() => {
        let factoryUsersApiService: FactoryUsersApiService = getTestBed().get(FactoryUsersApiService);
          factoryUsersApiService.getCurrentUser().subscribe(
            (res:any) => {
              console.log(res);
              expect(res).toBeDefined();
            }
          );
      }));
    
      it('should get Build Etl Reports(http server request)', async(() => {
        let factoryUsersApiService: FactoryUsersApiService = getTestBed().get(FactoryUsersApiService);
        factoryUsersApiService.getBuildEtlReport("[email protected]").subscribe(
          (res:any) => {
            console.log(res);
            expect(res).toBeDefined();
          }
        );
      }));
    
    });

    So i can say without a doubt, this code is for Angular2 Karma-Jasmine Http test.

    cheers! -Jaffar Khan