Angular2 - HTTP call unit testing

2019-06-10 00:43发布

I am a beginner of angular2.

My service.ts will be,

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import {Headers, RequestOptions, URLSearchParams}  from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Injectable()
export class HomeService {

    url : string;

    constructor(private _http: Http) {}

    getUserInfo(userId : string) {

        this.url = "http://localhost:9080/GetUserData";

        let content = new URLSearchParams();
        content.set('userId', userId.toString());

        let headers = new Headers();
        headers.append('Content-Type', 'application/x-www-form-urlencoded');

        return this._http
            .post(this.url, content.toString(), {headers: headers})
            .map((res: Response) => res.json())
            .catch(this.handleError);
    }

    handleError (error: Response | any) {

        let errMsg: string;
        if (error instanceof Response) {
            const body = error.json() || '';
            const err = body.error || JSON.stringify(body);
            errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
            errMsg = error.message ? error.message : error.toString();
        }
        console.error(errMsg);
        return Observable.throw(errMsg);
    }

}

I have written the unit test case as,

import { TestBed, async, inject } from '@angular/core/testing';
import { HomeService } from './home.service';
import { BaseRequestOptions, Response, ResponseOptions, Http } from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';
import {Observable} from 'rxjs/Observable';

describe('FacilityPopupService', () => {
  let subject: HomeService = null;
  let backend: MockBackend = null;
  let userid="UID1";

  beforeEach(() => {
    TestBed.configureTestingModule({
        providers: [
          HomeService,
          Response,
        BaseRequestOptions,
        MockBackend,
        {
          provide: Http,
          useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => {
            return new Http(backend, defaultOptions);
          },
          deps: [MockBackend, BaseRequestOptions],
        }

          ]
    });
  });

  beforeEach(inject([HomeService, MockBackend], (userService: HomeService, mockBackend: MockBackend) => {
    subject = userService;
    backend = mockBackend;

  }));

  it('get Facility list should call endpoint and return it\'s result', (done) => {
      backend.connections.subscribe((connection: MockConnection) => {
          let options = new ResponseOptions({
            body: JSON.stringify({ success: true })
          });
          connection.mockRespond(new Response(options));
      });

      subject.getUserInfo(userid)
        .subscribe((response) => {
            expect(response).toEqual({ success: true });
            done();
      });

  });

});

I want to write the test case for both success case and error case. I don't know how how to execute catch block. Also I don't know how to write test case for handleError method .

I cannot cannot cover all the possible scenarios here. Can you please help me to get 100% coverage for the service.ts.

2条回答
姐就是有狂的资本
2楼-- · 2019-06-10 01:12

You can use the below code for the positive case.

describe('HomeService',() =>{
    let homeService:HomeService,
        mockHttp;

        beforeEach(() => {
            mockHttp=jasmine.createSpyObject('mockHttp',['get'])
            homeService=new HomeService(mockHttp);

        });
        describe('GetbyID', =>{
            it('should get the detail of user with passed id', =>{
            let user={id:1,name:'some Name'}
                mockHttp.get.and.returnValue(Observable.of(false));
                homeService.getUserInfo(1);
                expect(mockHttp.get).toHaveBeenCalledWith('your url');

            });
        });
});

For negative case: Make a mistake in the URL and check if the call is failing and error handler method is invoked or not.

查看更多
一夜七次
3楼-- · 2019-06-10 01:17

For covering negative case you can mock response with non-200 status code. You can follow this example MockBackend.

 it('getUserInfo() while server is down', fakeAsync(() => {
       let result: any;
       let catchedError: any;
       this.userUser.getUserInfo(1)
           .then((userInfo: any) => result = userInfo)
           .catch((error: any) => catchedError = error);
       this.lastConnection.mockRespond(new Response(new ResponseOptions({
         status: 404, //here
         statusText: 'URL not Found',
       })));
       tick();
       expect(result).toBeUndefined();
       expect(catchedError).toBeDefined();
     }));
});
查看更多
登录 后发表回答