Метод jest.spyOn() является важным инструментом в
тестировании с использованием библиотеки Jest, особенно когда требуется
отслеживать вызовы методов и манипулировать их поведением во время
тестов. Он предоставляет возможность “шпионить” за функциями и методами,
без необходимости модификации их исходного кода. Это важная составляющая
для проверки взаимодействий внутри компонентов или классов, а также для
точного контроля над их поведением.
jest.spyOn()jest.spyOn() позволяет:
Метод jest.spyOn() принимает два обязательных
параметра:
Пример:
const obj = {
method: (a, b) => a + b,
};
const spy = jest.spyOn(obj, 'method');
// Вызов метода
obj.method(1, 2);
// Проверка вызова
expect(spy).toHaveBeenCalled();
expect(spy).toHaveBeenCalledWith(1, 2);
В этом примере мы создали объект с методом, шпионем за этим методом с
помощью jest.spyOn(), вызываем метод и проверяем, что он
был вызван с правильными аргументами.
С помощью jest.spyOn() можно не только отслеживать
вызовы методов, но и изменять их поведение, задав свою реализацию. Это
полезно, когда нужно имитировать результат работы метода без
необходимости зависеть от внешних факторов.
Пример:
const obj = {
fetchData: () => {
return 'real data';
},
};
const spy = jest.spyOn(obj, 'fetchData').mockReturnValue('mocked data');
// Теперь метод fetchData вернёт 'mocked data'
console.log(obj.fetchData()); // 'mocked data'
expect(spy).toHaveBeenCalled();
Здесь мы подменяем реализацию метода fetchData, чтобы он
возвращал заданное значение, а не реальное. Это позволяет нам
тестировать логику, не полагаясь на фактическое выполнение метода.
jest.spyOn()mockReturnValue(value): позволяет
задать значение, которое будет возвращено при вызове отслеживаемого
метода.
mockImplementation(fn): позволяет
задать произвольную реализацию для отслеживаемого метода, что полезно
для имитации сложных сценариев.
mockRestore(): восстанавливает
оригинальное поведение метода, если он был шпионен с помощью
jest.spyOn().
Пример использования с mockImplementation:
const obj = {
fetchData: () => 'real data',
};
const spy = jest.spyOn(obj, 'fetchData').mockImplementation(() => 'mocked data');
// Теперь fetchData будет возвращать 'mocked data', а не 'real data'
console.log(obj.fetchData()); // 'mocked data'
spy.mockRestore(); // Восстанавливаем исходную функцию
console.log(obj.fetchData()); // 'real data'
jest.spyOn() с классамиПри работе с классами jest.spyOn() может быть полезен
для тестирования методов экземпляров классов, а также для проверки того,
как методы взаимодействуют с другими частями системы.
Пример с классом:
class MyClass {
myMethod(a, b) {
return a + b;
}
}
const instance = new MyClass();
const spy = jest.spyOn(instance, 'myMethod');
// Вызов метода
instance.myMethod(2, 3);
// Проверка
expect(spy).toHaveBeenCalled();
expect(spy).toHaveBeenCalledWith(2, 3);
В этом примере мы создаём экземпляр класса, шпионяем за методом
myMethod, а затем проверяем, что метод был вызван с
правильными аргументами.
jest.spyOn() также полезен для тестирования
взаимодействий с внешними зависимостями, например, при тестировании
вызовов сторонних библиотек.
Пример с использованием стороннего метода:
const axios = require('axios');
jest.spyOn(axios, 'get').mockResolvedValue({ data: 'mocked data' });
axios.get('https://api.example.com/data').then(response => {
console.log(response.data); // 'mocked data'
});
Здесь мы шпионем за методом get из библиотеки
axios и возвращаем “мокированные” данные. Это позволяет
тестировать логику взаимодействия с внешними сервисами без реальных
сетевых запросов.
Восстановление оригинальной реализации: После
использования jest.spyOn() для отслеживания метода, важно
восстановить его исходное состояние с помощью
mockRestore(), если это необходимо. Иначе это может
привести к побочным эффектам в других тестах.
Поведение с асинхронными методами: При работе с
асинхронными методами следует учитывать, что вызовы, которые возвращают
промисы, также можно контролировать с помощью методов вроде
mockResolvedValue() или
mockRejectedValue().
Невозможность отслеживания конструкторов:
jest.spyOn() не может использоваться для отслеживания
вызовов конструкторов, так как это не является методом объекта. В таких
случаях используют другие подходы, например, шпионаж на методы
экземпляров.
jest.spyOn() в интеграционных тестахИнтеграционные тесты часто требуют отслеживания взаимодействий между
компонентами, модулями и сервисами. jest.spyOn() помогает
изолировать конкретные методы, отслеживать их вызовы и контролировать их
поведение.
Пример интеграционного теста:
class ApiService {
fetchData() {
return fetch('https://api.example.com/data').then(response => response.json());
}
}
const apiService = new ApiService();
jest.spyOn(apiService, 'fetchData').mockResolvedValue({ data: 'mocked data' });
test('fetchData returns mocked data', async () => {
const data = await apiService.fetchData();
expect(data).toEqual({ data: 'mocked data' });
});
Здесь мы тестируем интеграцию с внешним API, подменяя реальный ответ на «мокированные» данные, чтобы протестировать логику работы компонента без реальных запросов.
Метод jest.spyOn() является мощным инструментом для
отслеживания и манипулирования поведением методов и функций во время
тестирования. Он позволяет эффективно проверять взаимодействия в
системе, имитировать определённые поведения и изолировать код от внешних
зависимостей. Правильное использование jest.spyOn()
значительно улучшает качество тестов и делает их более
предсказуемыми.