Using jest.mock To Stub out API calls In Tests

Share on facebook
Share on google
Share on twitter
Share on linkedin
Photo by Caspar Camille Rubin on Unsplash

This is a quick blog on how I used jest.mock to create a mock of an ES6 class.

Mock objects are simulated objects that mimic the behaviour of real objects in controlled ways. — https://en.wikipedia.org/wiki/Mock_object

In my weather manager, I have two classes:

  • APIRequest: contains functions with API calls to openweathermap.org
  • Weather: formats the data received from the API calls

To the best of my knowledge, the purpose of using a mock for the APIRequest class is to ensure when tests for the Weather class methods (which include calls to methods in the APIRequest class) are run, actual API calls are not made.

Jest Mocks

The JavaScript testing library, Jest, has the option to mock ES6 classes.

When an instance of the Weather class is initialised, it creates a new instance of the APIRequest class, setting it to this.apiRequest:

export class Weather {
constructor() {
...
this.apiRequest = new APIRequest();
}

Using the getOneDayWeather function in the Weather class as an example, this method calls weatherOneDay() in the APIRequest class when it is invoked:

//a method in the Weather class
async getOneDayWeather() {
const todayWeather = await this.apiRequest.weatherOneDay();
return todayWeather;
}

To simulate the APIRequest function weatherOneDay() being called in the tests, the APIRequest class can be set as a mock. This is inputted before any tests relating to API calls:

jest.mock('../src/api_request')
...
beforeEach(() => {
APIRequest.mockClear();
});

The test below checks if calling the Weather function getOneDayWeather also calls the APIRequest function weatherOneDay:

jest.mock('../src/api_request')
it('checks if getOneDayWeather calls the APIRequest method weatherOneDay', () => {
const weather = new Weather();
weather.getOneDayWeather();
const mockAPIRequestInstance = APIRequest.mock.instances[0];
const mockWeatherOneDay = mockAPIRequestInstance.weatherOneDay;
expect(mockWeatherOneDay).toHaveBeenCalledTimes(1);
});

To clarify the above, a mock instance of the APIRequest class is set to mockAPIRequestInstance:

const mockAPIRequestInstance = APIRequest.mock.instances[0]

A mock instance of the APIRequest method weatherOneDay is created with:

const mockWeatherOneDay = mockAPIRequestInstance.weatherOneDay

This test is checking that the mock instance of the weatherOneDay method has been called once after weather.getOneDayWeather()is called:

expect(mockWeatherOneDay).toHaveBeenCalledTimes(1)

And that’s how I used jest.mock to stub out an API call in a test ?

What’s next:

  • Rename my functions (they could be much clearer)
  • Deploy the weather manager to Heroku

Helpful resources: