Мокирование конкретного метода класса в Jest: руководство
Быстрый ответ
Чтобы застабить выборный метод класса в Jest, превосходно подходит комбинация функций jest.spyOn()
и mockImplementation()
либо mockReturnValue()
. Все просто:
import MyClass from './MyClass';
// Начинаем стабировать метод
const mockMyMethod = jest.spyOn(MyClass.prototype, 'myMethod');
// Устанавливаем стабовое возвращаемое значение
mockMyMethod.mockReturnValue('стабированное значение');
В результате переопределяем метод myMethod
, который, без оказания влияния на другие методы, присваивает возвращаемое значение 'стабированное значение'
при каждом экземпляре MyClass
.
Рассмотрим методы по отдельности
Стабирование конкретного экземпляра метода
Для стабирования метода конкретного экземпляра:
let instance = new MyClass();
jest.spyOn(instance, 'myMethod').mockReturnValue('Это уникально стабированный метод');
Остальные экземпляры MyClass
будут продолжать работать в обыкновенном режиме, без стаба.
Как быть со статическими методами?
Со статическими методами поступаем аналогично:
jest.spyOn(MyClass, 'staticMyMethod').mockReturnValue('Статический метод застабирован');
Здесь мы обращаемся прямо к классу, а не к его прототипу.
Доделки после прохождения тестов
Для очистки всех стабов после прохождения тестов используется:
afterAll(() => {
jest.restoreAllMocks();
});
Если нужно восстановить работу только одного стабированного метода:
mockMyMethod.mockRestore();
Частичное стабирование
Для исключения стабирования всех методов с использованием jest.mock()
, сохранив при этом остальные методы в их оригинальном состоянии:
jest.mock('./MyClass', () => {
const originalModule = jest.requireActual('./MyClass');
return {
...originalModule,
myMethod: jest.fn().mockReturnValue('стабированное значение'),
};
});
Управление стрелочными функциями
Если потребуется застабировать стрелочную функцию, то проще её переписать в обычный метод класса для упрощения тестирования:
class MyClass {
myMethod = function() {
return 'реальное значение';
}
}
Переопределение методов? Есть такое!
Создание подкласса с переопределением метода — еще один вариант стабирования:
class MockedClass extends MyClass {
myMethod() {
return 'стабированное значение';
}
}
Теперь MockedClass
использовать в тестах.
Подсказки для TypeScript
В TypeScript придется внимательно работать с приведением типов при стабировании:
jest.mock('./MyClass');
const { MyClass } = jest.requireActual('./MyClass');
const mockedMyClass = new MyClass() as jest.Mocked<MyClass>;
mockedMyClass.myMethod.mockReturnValue('стабированное значение');
Визуализация
Рассмотрим ваш класс как набор инструментов, где каждый метод — отдельный инструмент. Нам требуется застабировать лишь молоток, не влияя на работоспособность остальных инструментов.
class Toolbox {
hammer() { return 'бах!'; }
wrench() { return 'вертим!'; }
screwdriver() { return 'поворот!'; }
}
// Стабируем метод hammer
jest.spyOn(Toolbox.prototype, 'hammer').mockImplementation(() => 'стабировано-бах!');
До: Все инструменты полностью функциональны.
🧰: [🔨 ➜ 'бах!', 🔧 ➜ 'вертим!', 🪛 ➜ 'поворот!']
После: Молоток стабирован, остальные инструменты снова функционируют в обыкновенном режиме.
🧰: [🔨 ➜ 'стабировано-бах!', 🔧 ➜ 'вертим!', 🪛 ➜ 'поворот!']
Проверка стабов на работоспособность
Проверим, работают ли стабы посредством проверки возвращаемого значения и количества вызовов:
expect(mockedMyClass.myMethod()).toBe('стабированное значение');
expect(mockedMyClass.myMethod).toHaveBeenCalledTimes(1);
Полезные материалы
- Официальному справочнику Jest по стаб-функциям обучаетеся у профессионалов!
- Учебное пособие по Jest для TypeScript — всё о стабировании в TypeScript. Инструменты для более глубокого анализа!
- Справочник по использованию
jest.spyOn()
— путеводная звезда в данных понятиях. - Погружение в стаб-функции Jest от Рика Хенлона II.
- Еще больше данных о стабировании в Jest — на прямом сайте Jest.
- Шпаргалка Jest на GitHub — когда требуется быстро освежить знания.