Jest позволяет тестировать функции, которые вызывают внешние API, путем имитации (mocking) вызовов API. Это делается с помощью функциональности имитации Jest, которая позволяет заменить фактическую реализацию функции на фейковую или “имитированную” версию.
Шаги для тестирования функции, вызывающей внешний API:
- Импортируйте модуль с функцией, которую хотите протестировать.
- Используйте
jest.mock()для замены функции на имитированную версию. - Определите, что должна возвращать имитированная функция при вызове.
- Напишите утверждения (assertions) для проверки правильности поведения вашей функции с имитированными данными.
Предположим, у вас есть функция fetchData, которая вызывает внешний API:
export const fetchData = async () => {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
return data;
};import { fetchData } from "./api";
export const getData = async () => {
const data = await fetchData();
return data.name;
};import { getData } from "./myFunction";
import { fetchData } from "./api";
// Имитируем функцию fetchData
jest.mock("./api");
test("getData returns the name from the API", async () => {
// Определяем, что должна возвращать имитированная функция
fetchData.mockResolvedValue({ name: "John Doe" });
// Вызываем функцию, которую хотим протестировать
const result = await getData();
// Проверяем, что функция ведет себя правильно
expect(result).toBe("John Doe");
expect(fetchData).toHaveBeenCalled();
});- Импорт модуля и имитация: Импортируем функцию
fetchDataи используемjest.mock('./api')для замены ее на имитированную версию. - Определение возвращаемого значения: Используем
fetchData.mockResolvedValue({ name: 'John Doe' }), чтобы определить, что должна возвращать имитированная функция. - Вызов тестируемой функции: Вызываем функцию
getData, которую хотим протестировать. - Написание утверждений: Проверяем, что функция
getDataвозвращает ожидаемое значение и что имитированная функцияfetchDataбыла вызвана.
Дополнительные примеры:
Имитация отклоненного промиса:
test("getData handles API error", async () => {
fetchData.mockRejectedValue(new Error("API error"));
await expect(getData()).rejects.toThrow("API error");
expect(fetchData).toHaveBeenCalled();
});Имитация функции с параметрами:
test("getData handles different API responses", async () => {
fetchData.mockImplementation((url) => {
if (url === "https://api.example.com/data") {
return Promise.resolve({ name: "John Doe" });
} else {
return Promise.resolve({ name: "Jane Smith" });
}
});
const result1 = await getData("https://api.example.com/data");
const result2 = await getData("https://api.example.com/other");
expect(result1).toBe("John Doe");
expect(result2).toBe("Jane Smith");
expect(fetchData).toHaveBeenCalledTimes(2);
});