Tom
Tom

Reputation: 4033

How to unit test nested HTTP Calls

I have the following function I'm trying to unit test:

async fetchGreatHouseByName(name: string) {
  const [house] = await this.httpGetHouseByName(name);
  const currentLord = house.currentLord ? house.currentLord : '957';
  const result: any = await this.httpGetLord(currentLord);
  const character = Characters.default.find(char => char.characterName === result.name);
  return {...house, character};
}

Inside of this function are multiple HTTP GET calls. I know how to test them, but how do I handle nested HTTP Calls, which each is a Promise.

What I got:

it('should get house from http', done => {
  const httpMock: HttpTestingController = TestBed.inject(HttpTestingController);

  const mockResponse = {
    name: 'House One',
    currentLord: 'Some Lord'
  };

  service.fetchGreatHouseByName('House One').then((house: House) => {
    expect(house).toBeTruthy();
    console.log(house);
  });

  const mockRequest = httpMock.expectOne(
    'https://www.anapioficeandfire.com/api/houses?name=House%20Lannister%20of%20Casterly%20Rock'
  );

  mockRequest.flush(mockResponse);

});

So httpGetHouseByName typically returns something like mockRequest. And httpGetLord and object containing name among other properties. Do I need one more mock for this HTTP call and if so, how do I use it?

Upvotes: 0

Views: 809

Answers (1)

AliF50
AliF50

Reputation: 18849

I think calling the function should put two HTTP calls in queue. Try flushing both calls in series and putting your assertions in the .then block.

it('should get house from http', done => {
  const httpMock: HttpTestingController = TestBed.inject(HttpTestingController);

  const mockResponse = {
    name: 'House One',
    currentLord: 'Some Lord'
  };

  service.fetchGreatHouseByName('House One').then((house: House) => {
    expect(house).toBeTruthy();
    console.log(house);
    // your other assertions here
  });

  const mockRequest = httpMock.expectOne(
    'https://www.anapioficeandfire.com/api/houses?name=House%20Lannister%20of%20Casterly%20Rock'
  );

  mockRequest.flush(mockResponse);

  const response = {
     // mock response of httpGetLord here
    };
  const request = httpMock.expectOne(/* url of httpGetLord*/);
  request.flush(response);
});

Upvotes: 1

Related Questions