🎉 Вы можете найти новые и обновленные сообщения на ellehallal.dev

Это краткий блог о том, как я использовал jest.mock для создания макета класса ES6.

Объекты-макеты – это смоделированные объекты, которые контролируемым образом имитируют поведение реальных объектов. — https://en.wikipedia.org/wiki/Mock_object

В моем менеджере погоды у меня есть два класса:

  • APIRequest: содержит функции с вызовами API к openweathermap.org.
  • Погода: форматирует данные, полученные от вызовов API.

Насколько мне известно, цель использования макета для класса APIRequest состоит в том, чтобы гарантировать, что при выполнении тестов для методов класса Weather (которые включают вызовы методов в классе APIRequest) фактические вызовы API не выполняются.

Шутки

В библиотеке тестирования JavaScript Jest есть возможность издеваться над классами ES6.

Когда экземпляр класса Weather инициализируется, он создает новый экземпляр класса APIRequest, присваивая ему значение this.apiRequest:

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

Используя в качестве примера функцию getOneDayWeather в классе Weather, этот метод вызывает weatherOneDay() в классе APIRequest при вызове:

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

Чтобы имитировать функцию APIRequest weatherOneDay(), вызываемую в тестах, класс APIRequest можно установить как макет. Это вводится перед любыми тестами, связанными с вызовами API:

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

Приведенный ниже тест проверяет, вызывает ли вызов функции Weather getOneDayWeather также функцию APIRequest 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);
    });

Чтобы прояснить вышеизложенное, для фиктивного экземпляра класса APIRequest установлено значение mockAPIRequestInstance:

const mockAPIRequestInstance = APIRequest.mock.instances[0]

Макетный экземпляр метода APIRequest weatherOneDay создается с помощью:

const mockWeatherOneDay = mockAPIRequestInstance.weatherOneDay

Этот тест проверяет, что фиктивный экземпляр метода weatherOneDay был вызван один раз после вызова weather.getOneDayWeather():

expect(mockWeatherOneDay).toHaveBeenCalledTimes(1)

И вот как я использовал jest.mock, чтобы заглушить вызов API в тесте 🥳

Что дальше:

  • Переименуйте мои функции (они могут быть намного понятнее)
  • Разверните менеджера погоды на Heroku

Полезные ресурсы: