API-тестирование является важной частью процесса разработки приложений, так как оно помогает убедиться, что сервер правильно обрабатывает запросы и отвечает на них с ожидаемыми данными. Jest, как популярный инструмент для тестирования JavaScript, предоставляет мощные возможности для тестирования API. В этой главе рассмотрены принципы и подходы к тестированию API-запросов с использованием Jest.
Для тестирования API с помощью Jest необходимо настроить несколько вещей. Обычно это включает в себя установку необходимых библиотек и настройку самого Jest для работы с HTTP-запросами.
Установка зависимостей Чтобы тестировать API,
необходимо установить Jest, а также дополнительные библиотеки для работы
с HTTP-запросами, такие как axios или
node-fetch. Например, для установки через npm можно
выполнить следующую команду:
npm install --save-dev jest axiosНастройка Jest В файле конфигурации Jest
(jest.config.js) можно указать различные параметры, такие
как тайм-ауты для тестов и другие настройки:
module.exports = {
testTimeout: 10000, // Увеличение тайм-аута для API запросов
// другие параметры конфигурации
};Для начала рассмотрим пример тестирования простого GET-запроса. Допустим, у нас есть API, который возвращает список пользователей.
// Пользовательский сервис (например, src/userService.js)
import axios from 'axios';
export const getUsers = async () => {
const response = await axios.get('https://jsonplaceholder.typicode.com/users');
return response.data;
};
Теперь создадим тест для этой функции с использованием Jest.
// Тест для userService (например, src/userService.test.js)
import { getUsers } from './userService';
import axios from 'axios';
jest.mock('axios'); // Мокаем axios
describe('getUsers', () => {
it('должен возвращать список пользователей', async () => {
// Заготовка мока
const users = [{ id: 1, name: 'John Doe' }];
axios.get.mockResolvedValue({ data: users });
const result = await getUsers();
expect(result).toEqual(users);
});
it('должен выбросить ошибку, если запрос не удался', async () => {
axios.get.mockRejectedValue(new Error('Network Error'));
await expect(getUsers()).rejects.toThrow('Network Error');
});
});
В этом примере:
jest.mock() для создания мока библиотеки
axios. Это позволяет имитировать поведение HTTP-запросов,
не отправляя реальные запросы.mockResolvedValue() позволяет задать успешный
результат запроса, а mockRejectedValue() — ошибку, которую
должен выбросить запрос.API часто работает с асинхронными операциями, и важно правильно
тестировать такие запросы. Jest поддерживает асинхронные тесты с
использованием async/await, что позволяет тестировать
работу API синхронным способом.
Пример тестирования асинхронного POST-запроса:
// Пример POST запроса
import axios from 'axios';
export const createUser = async (user) => {
const response = await axios.post('https://jsonplaceholder.typicode.com/users', user);
return response.data;
};
Тестирование этого запроса:
import { createUser } from './userService';
import axios from 'axios';
jest.mock('axios');
describe('createUser', () => {
it('должен создавать нового пользователя', async () => {
const newUser = { name: 'Jane Doe' };
const createdUser = { id: 1, name: 'Jane Doe' };
axios.post.mockResolvedValue({ data: createdUser });
const result = await createUser(newUser);
expect(result).toEqual(createdUser);
});
it('должен выбросить ошибку при неудачном запросе', async () => {
const newUser = { name: 'Jane Doe' };
axios.post.mockRejectedValue(new Error('Network Error'));
await expect(createUser(newUser)).rejects.toThrow('Network Error');
});
});
Этот пример также использует моки для симуляции поведения API, но уже для метода POST. Также показано, как можно проверять ошибки при неудачных запросах.
Иногда бывает полезно мокировать данные с использованием специальных
фейковых серверов, таких как msw (Mock Service Worker). Это
позволяет более гибко работать с запросами, не завися от реальных
серверов.
Пример интеграции с msw:
npm install msw --save-dev
// Пример использования msw
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { getUsers } from './userService';
const server = setupServer(
rest.get('https://jsonplaceholder.typicode.com/users', (req, res, ctx) => {
return res(ctx.json([{ id: 1, name: 'John Doe' }]));
})
);
// Настройка перед и после тестов
beforeAll(() => server.listen());
afterAll(() => server.close());
afterEach(() => server.resetHandlers());
describe('getUsers', () => {
it('должен возвращать список пользователей', async () => {
const result = await getUsers();
expect(result).toEqual([{ id: 1, name: 'John Doe' }]);
});
});
В этом примере используется библиотека msw для перехвата
HTTP-запросов и возврата фейковых ответов. Это позволяет эмулировать
поведение API и тестировать функциональность без необходимости в
реальном сервере.
Для более глубокой проверки работы API важно также проверять не только данные в ответе, но и статус-коды HTTP и заголовки.
Пример:
import { getUsers } from './userService';
import axios from 'axios';
jest.mock('axios');
describe('getUsers', () => {
it('должен возвращать статус 200 и данные пользователей', async () => {
const users = [{ id: 1, name: 'John Doe' }];
axios.get.mockResolvedValue({
status: 200,
data: users,
headers: { 'content-type': 'application/json' }
});
const result = await getUsers();
expect(result).toEqual(users);
expect(axios.get).toHaveBeenCalledWith('https://jsonplaceholder.typicode.com/users');
});
it('должен проверять заголовки ответа', async () => {
const response = {
status: 200,
data: [{ id: 1, name: 'John Doe' }],
headers: { 'content-type': 'application/json' }
};
axios.get.mockResolvedValue(response);
const result = await getUsers();
expect(result).toEqual(response.data);
expect(response.headers['content-type']).toBe('application/json');
});
});
Здесь проверяется не только правильность данных, но и проверка правильности заголовков ответа и статус-кода.
В реальных приложениях API-запросы могут быть связаны и зависят друг от друга. В таких случаях полезно тестировать сценарии, где несколько запросов выполняются параллельно или последовательно.
Пример параллельных запросов:
import axios from 'axios';
export const fetchUserData = async (userId) => {
const userResponse = await axios.get(`https://jsonplaceholder.typicode.com/users/${userId}`);
const postsResponse = await axios.get(`https://jsonplaceholder.typicode.com/posts?userId=${userId}`);
return { user: userResponse.data, posts: postsResponse.data };
};
Тестирование:
import { fetchUserData } from './userService';
import axios from 'axios';
jest.mock('axios');
describe('fetchUserData', () => {
it('должен загружать данные о пользователе и его постах', async () => {
const user = { id: 1, name: 'John Doe' };
const posts = [{ id: 1, title: 'Post 1' }];
axios.get.mockResolvedValueOnce({ data: user }).mockResolvedValueOnce({ data: posts });
const result = await fetchUserData(1);
expect(result).toEqual({ user, posts });
});
});
Этот тест проверяет работу с несколькими параллельными запросами.
Метод mockResolvedValueOnce() используется для создания
разных ответов для каждого запроса.
Jest предоставляет гибкие возможности для тестирования API-запросов. С помощью мокирования, асинхронных функций и библиотек для создания фейковых серверов можно легко тестировать как отдельные запросы, так и сложные сценарии с множеством взаимозависимых запросов.