Интеграционные тесты фокусируются на проверке взаимодействий между компонентами приложения. В контексте веб-приложений это часто означает тестирование HTTP-запросов и ответов между сервером и клиентом, а также взаимодействия с базой данных. Mocha является одним из популярных инструментов для реализации таких тестов в JavaScript, и в этой главе рассмотрены основные подходы к написанию интеграционных тестов HTTP-запросов с использованием Mocha.
Интеграционные тесты для HTTP-запросов обеспечивают проверку работоспособности веб-API, включая правильность ответов на запросы, статусные коды, формат данных и корректность обработки ошибок. Эти тесты проверяют не только работу отдельных функций или модулей, но и то, как компоненты взаимодействуют между собой в реальном приложении.
Для работы с HTTP в Mocha чаще всего используют внешние библиотеки, такие как supertest. Это мощная утилита для тестирования HTTP-API, которая позволяет выполнять запросы к серверу и проверять их ответы.
Для создания тестов для HTTP-запросов необходимо настроить серверное окружение. Обычно для этого используется сервер, запущенный на определённом порту, с базой данных или мока для упрощённых тестов.
const app = require('../app'); // Импортируем приложение
const supertest = require('supertest');
const request = supertest(app);
describe('Интеграционные тесты API', function () {
it('Тестирование GET-запроса', function (done) {
request
.get('/api/resource')
.expect(200)
.end(function (err, res) {
if (err) return done(err);
done();
});
});
});
В этом примере используется supertest для отправки
GET-запроса на эндпоинт /api/resource. Метод
.expect(200) проверяет, что ответ имеет статус 200
(OK).
Кроме проверки статусных кодов, важно проверять, соответствует ли содержимое ответа ожиданиям. Например, для JSON-ответов можно проверять структуру данных.
describe('Тестирование GET-запроса с JSON-ответом', function () {
it('Получение списка пользователей', function (done) {
request
.get('/api/users')
.expect(200)
.expect('Content-Type', /json/)
.end(function (err, res) {
if (err) return done(err);
// Проверка наличия ожидаемых данных в теле ответа
const users = res.body;
users.should.be.an('array');
users[0].should.have.property('id');
users[0].should.have.property('name');
done();
});
});
});
В этом примере используется библиотека should.js для
проверки типа данных в ответе и наличия обязательных полей в объекте.
Метод .expect('Content-Type', /json/) гарантирует, что
ответ будет в формате JSON.
Для POST-запросов важно проверять не только статусный код, но и правильность обработки данных, переданных в теле запроса. Пример:
describe('Тестирование POST-запроса', function () {
it('Создание нового пользователя', function (done) {
const user = { name: 'John Doe', email: 'john.doe@example.com' };
request
.post('/api/users')
.send(user)
.expect(201)
.expect('Content-Type', /json/)
.end(function (err, res) {
if (err) return done(err);
const createdUser = res.body;
createdUser.should.have.property('id');
createdUser.name.should.equal(user.name);
createdUser.email.should.equal(user.email);
done();
});
});
});
Здесь выполняется POST-запрос для создания нового пользователя. Метод
.send(user) передаёт данные в теле запроса, а проверка на
статус 201 подтверждает успешное создание ресурса.
Для PUT и DELETE запросов аналогично проводятся тесты на проверку правильности обработки данных и изменений.
describe('Тестирование PUT-запроса', function () {
it('Обновление данных пользователя', function (done) {
const updatedUser = { name: 'Jane Doe', email: 'jane.doe@example.com' };
request
.put('/api/users/1')
.send(updatedUser)
.expect(200)
.end(function (err, res) {
if (err) return done(err);
const user = res.body;
user.should.have.property('id').equal(1);
user.name.should.equal(updatedUser.name);
user.email.should.equal(updatedUser.email);
done();
});
});
});
describe('Тестирование DELETE-запроса', function () {
it('Удаление пользователя', function (done) {
request
.delete('/api/users/1')
.expect(204)
.end(function (err, res) {
if (err) return done(err);
done();
});
});
});
Для DELETE-запроса проверяется статус 204, который подтверждает успешное удаление ресурса.
Важно тестировать также и обработку ошибок. Для этого можно создавать запросы, которые будут приводить к ошибке, например, с некорректными данными или неправильными путями.
describe('Тестирование ошибок', function () {
it('Попытка получения несуществующего ресурса', function (done) {
request
.get('/api/nonexistent')
.expect(404)
.end(function (err, res) {
if (err) return done(err);
done();
});
});
});
Этот тест проверяет, что при обращении к несуществующему ресурсу сервер вернёт ошибку 404.
Интеграционные тесты часто требуют взаимодействия с реальной базой данных. Это можно настроить так, чтобы тесты выполнялись в отдельной тестовой базе данных, а после каждого теста база очищалась.
Для создания и очистки базы данных можно использовать специальные библиотеки, такие как mongodb-memory-server для MongoDB.
Пример настройки с использованием базы данных:
const mongoose = require('mongoose');
const { MongoMemoryServer } = require('mongodb-memory-server');
let mongoServer;
before(async () => {
mongoServer = await MongoMemoryServer.create();
const uri = mongoServer.getUri();
await mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true });
});
after(async () => {
await mongoose.connection.dropDatabase();
await mongoose.connection.close();
await mongoServer.stop();
});
Здесь MongoDB запускается в памяти, и база данных очищается после выполнения тестов.
Большинство HTTP-запросов выполняются асинхронно, поэтому важно
правильно работать с асинхронностью в тестах. Mocha поддерживает работу
с асинхронными функциями с помощью done,
Promise или async/await.
Пример с использованием async/await:
describe('Асинхронный тест', function () {
it('Проверка асинхронного запроса', async function () {
const res = await request.get('/api/resource');
res.status.should.equal(200);
});
});
Такой подход делает тесты более читаемыми и удобными для работы с асинхронными операциями.
Интеграционные HTTP тесты играют ключевую роль в обеспечении качества веб-приложений. Использование Mocha в сочетании с такими инструментами, как supertest, позволяет эффективно тестировать API, проверяя как корректность ответов на запросы, так и взаимодействие с базой данных. Важно учитывать все возможные аспекты работы сервера, включая обработку ошибок, статусные коды и содержание ответа.