11

My components.ts is,

 getHomePageData() : void{
    this.homeservice.getHomePageData()
          .subscribe(
              data =>   {

                            //console.log("response status ################### "+data.status);
                            //console.log("getUserData response ************ \n"+JSON.stringify(data));
                            this.defaultFacilityId = data.response.defaultFacilityId;
                            this.defaultFacilityName = data.response.defaultFacilityName;
                            this.enterpriseId = data.response.enterpriseId;
                            this.enterpriseName = data.response.enterpriseName;
                            this.facilityList = data.response.facilityList;
                            this.userName = data.response.userName;

                            this.showDefaultPopoup();
                        },
              error =>  {
                            console.error(error);
                            //this.errorMessage="Technical error - Contact Support team !" ;
                        }
          );

  }

So my component.spec.ts is ,

 it('getHomePageData with SUCCESS - getHomePageData()', () => {
    backend.connections.subscribe((connection: MockConnection) => {
      //expect(connection.request.url).toEqual('http://localhost:8080/MSMTestWebApp/UDM/UdmService/Home/');
      expect(connection.request.url).toEqual('http://192.168.61.158:9080/GetUserData');

      expect(connection.request.method).toEqual(RequestMethod.Get);
      expect(connection.request.headers.get('Content-Type')).toEqual('application/json');
      let options = new ResponseOptions({
        body:
        {
          "request": { "url": "/getUserData" },
          "response": {
                 "defaultFacilityName":"3M Health Information Systems",
                  "enterpriseId":"11.0",
                  "enterpriseName":"HSA Enterprise",
                  "defaultFacilityId": "55303.0",
                  "userName":"Anand"
          },
          "error": ""
        },
        status : 200
      });

      connection.mockRespond(new Response(options));

    });

     backend.connections.subscribe((data) => {
      //expect(data.response.facilityId).toEqual("55303.0");
      //expect(subject.handleError).toHaveBeenCalled();
    })

    service.getHomePageData().subscribe((data) => {
          //expect(videos.length).toBe(4);
          expect(data.response.defaultFacilityId).toEqual("55303.0");
          component.defaultFacilityId = data.response.defaultFacilityId;
          component.defaultFacilityName = data.response.defaultFacilityName;
          component.enterpriseId = data.response.enterpriseId;
          component.enterpriseName = data.response.enterpriseName;
          component.userName = data.response.userName;
          console.log("$$$$$$$$$$$$$$$$**********$$$$$$$$$$$$$$$$$$$$$");
      });

  });

When i try to run test case. It got passed. But while I look into the code coverage, it doesn't cover the code shown in red belowenter image description here

Please help to get the full code coverage. Thanks.

Human Being
  • 8,269
  • 28
  • 93
  • 136
  • Something wrong with your example. Can you add `TestBed.configureTestingModule` section? How many assertions has test when it got passed? Did you tried to add `async` / `fakeAsync` to test? – Aleksandr Petrovskij Mar 19 '17 at 05:08
  • @HumanBeing Could you provide coverage config, what did you use angular-cli or custom webpack config ? – BILL Mar 20 '17 at 19:19

2 Answers2

6

In the test you've shown here you don't seem to be calling getHomePageData() from your component

Try building your test like this:

import { fakeAsync, tick } from '@angular/core/testing';
...
it('getHomePageData with SUCCESS - getHomePageData()', fakeAsync(() => {
  backend.connections.subscribe((connection: MockConnection) => {
  //expect(connection.request.url).toEqual('http://localhost:8080/MSMTestWebApp/UDM/UdmService/Home/');
  expect(connection.request.url).toEqual('http://192.168.61.158:9080/GetUserData');

  expect(connection.request.method).toEqual(RequestMethod.Get);
  expect(connection.request.headers.get('Content-Type')).toEqual('application/json');
  let options = new ResponseOptions({
    body:
    {
      "request": { "url": "/getUserData" },
      "response": {
             "defaultFacilityName":"3M Health Information Systems",
              "enterpriseId":"11.0",
              "enterpriseName":"HSA Enterprise",
              "defaultFacilityId": "55303.0",
              "userName":"Anand"
      },
      "error": ""
    },
    status : 200
  });

  connection.mockRespond(new Response(options));

  });

  // If this function is not automatically called in the component initialisation
  component.getHomePageData();
  tick();
  //you can call expects on your component's properties now
  expect(component.defaultFacilityId).toEqual("55303.0");

});

FakeAsync allows you to write tests in a more linear style so you no longer have to subscribe to the service function to write your expectations.

In a FakeAsync test function you can call tick() after a call where an asynchronous operation takes place to simulate a passage of time and then continue with the flow of your code.

You can read more about this here: https://angular.io/docs/ts/latest/testing/#!#fake-async

EDIT - Error Case

To test the error logic you can call mockError or set up an error response using mockRespond on your connection:

it('getHomePageData with ERROR- getHomePageData()', fakeAsync(() => {
  backend.connections.subscribe((connection: MockConnection) => {
    if (connection.request.url === 'http://192.168.61.158:9080/GetUserData') {
        // mockError option
        connection.mockError(new Error('Some error'));
        // mockRespond option
        connection.mockRespond(new Response(new ResponseOptions({
          status: 404,
          statusText: 'URL not Found',
        })));
    }

  component.getHomePageData();
  tick();
  //you can call expects now
  expect(connection.request.url).toEqual('http://192.168.61.158:9080/GetUserData');
  expect(connection.request.method).toEqual(RequestMethod.Get);
  expect(connection.request.headers.get('Content-Type')).toEqual('application/json');
  expect('you can test your error logic here');
});

What we're doing inside the subscription is making sure that anytime the GetUserData endpoint is called within this test method it will return an error.

Because we test errors and successes separately in the success test there's no need to add the error related settings in the request options.

Borquaye
  • 756
  • 3
  • 9
  • Thanks for the valuable answer... Coverage for **success case** is fine . Now the code coverage need to be covered for **error** case ? Can u please help me ? – Human Being Mar 27 '17 at 16:09
  • No worries, I've edited the answer to add the error situation – Borquaye Mar 28 '17 at 09:18
2

Are you using JSON data? Then you should probably use map() before using .subscribe().

.map((res:Response) => res.json())

Try organizing your code like this:

ngOnInit() {
this.getHomePageData();
}

getHomePageData() {
 this.http.get('your.json')
  .map((res:Response) => res.json())
  .subscribe(
    data => { 
      this.YourData = data
    },
    err => console.error(err),
    () => console.log('ok')
  );
}

Hope it helps,

Cheers

mlk
  • 388
  • 2
  • 10
  • I am using the **map** in the **service.ts** . In the **component.ts** I cannot use **map** function. – Human Being Mar 19 '17 at 04:38
  • I think it is woth giving it a try. Otherwise, try to get your data where you use map, service.ts. – mlk Mar 19 '17 at 19:43
  • In **service.ts** Ivan able to cover 100 percentage coverage. Both success and failure case. Here in **component.ts** , may be **subscribe** creates problems. – Human Being Mar 21 '17 at 09:45