CommonJS — это спецификация для модульной системы в JavaScript, которая предназначена для использования в серверных средах, таких как Node.js. Она определяет стандарт для организации кода в виде отдельных модулей с их импортом и экспортом, что обеспечивает более удобную работу с кодом, масштабируемость и повторное использование.
В контексте тестирования с Mocha, CommonJS является основным способом работы с модулями. Mocha поддерживает CommonJS из коробки, что позволяет организовывать тесты, разделяя их на несколько файлов и модуляризуя их для удобства и простоты сопровождения.
В CommonJS каждый файл является отдельным модулем. Это означает, что внутри одного файла можно определить функции, объекты или переменные, которые будут доступны в других файлах через механизм экспорта и импорта.
Для того чтобы экспортировать функциональность из модуля в CommonJS,
используется объект module.exports. Это позволяет другим
файлам подключать и использовать функциональность, определённую в другом
модуле.
Пример:
// utils.js
function add(a, b) {
return a + b;
}
module.exports = {
add
};
В этом примере в модуле utils.js определяется функция
add, которая экспортируется с помощью
module.exports. Таким образом, другие модули могут её
использовать.
Для того чтобы использовать функциональность из другого модуля,
применяется функция require. Она позволяет подключить
другой файл и получить доступ к его экспортам.
Пример:
// test.js
const utils = require('./utils');
console.log(utils.add(2, 3)); // 5
Здесь файл test.js использует функцию add
из модуля utils.js, импортируя её через
require.
Mocha использует CommonJS для организации тестов и предоставляет встроенную поддержку для работы с модулями. Для тестирования с использованием Mocha обычно создаются отдельные файлы для каждой группы тестов. Каждый файл является модулем, который экспортирует определённую функциональность, такую как тесты, хелперы и утилиты.
С помощью CommonJS можно разделить тесты по файлам, каждый из которых экспортирует набор тестов, соответствующих определённой функции или классу. Например, можно создать файл для тестирования утилит и подключить его в основной тестовый файл.
Пример:
// utils.test.js
const assert = require('assert');
const utils = require('./utils');
describe('Utils', function() {
describe('#add()', function() {
it('должен возвращать правильный результат', function() {
assert.strictEqual(utils.add(2, 3), 5);
});
});
});
В этом примере тесты для функции add из модуля
utils.js находятся в файле utils.test.js.
Используя describe и it, можно организовать
тесты в структуру, которая будет легко расширяться.
Когда тесты становятся более сложными, их можно разбить на несколько модулей для удобства работы. Например, можно создать файл с набором тестов для работы с конкретной функцией или объектом, а затем подключить эти тесты в главный файл тестирования.
Пример:
// add.test.js
const assert = require('assert');
const utils = require('./utils');
describe('add', function() {
it('должен корректно складывать два числа', function() {
assert.strictEqual(utils.add(1, 2), 3);
});
it('должен возвращать отрицательное число для отрицательных аргументов', function() {
assert.strictEqual(utils.add(-1, -2), -3);
});
});
Затем, основной файл тестирования может выглядеть следующим образом:
// test.js
require('./add.test');
require('./subtract.test'); // добавляем другие файлы тестов по мере необходимости
Такой подход помогает поддерживать код организованным и легко расширяемым, особенно когда проект растёт.
При тестировании часто возникает необходимость в создании вспомогательных функций и утилит, которые могут быть использованы в различных тестах. CommonJS позволяет удобно организовать такие хелперы в отдельные модули и импортировать их по мере необходимости.
Пример:
// helpers.js
function mockDate(dateString) {
return new Date(dateString);
}
module.exports = {
mockDate
};
// test.js
const helpers = require('./helpers');
const assert = require('assert');
describe('Date testing', function() {
it('должен работать с мокированными датами', function() {
const mock = helpers.mockDate('2022-01-01');
assert.strictEqual(mock.getFullYear(), 2022);
});
});
В этом примере модуль helpers.js экспортирует функцию
mockDate, которая используется в тестах для мокирования
дат. Это позволяет избежать дублирования кода и делать тесты более
читаемыми.
В Mocha можно легко работать с асинхронными тестами, используя
возможности CommonJS. Mocha поддерживает асинхронные тесты с
использованием коллбеков, промисов и async/await. Чтобы
Mocha знал, что тест асинхронный, необходимо либо передать коллбек в
функцию it, либо вернуть промис, либо использовать
async/await.
Пример с коллбеком:
const assert = require('assert');
const utils = require('./utils');
describe('Utils async', function() {
it('должен корректно складывать числа асинхронно', function(done) {
utils.addAsync(2, 3, function(result) {
assert.strictEqual(result, 5);
done();
});
});
});
Пример с промисом:
describe('Utils async', function() {
it('должен корректно складывать числа асинхронно', function() {
return utils.addAsync(2, 3).then(result => {
assert.strictEqual(result, 5);
});
});
});
Пример с async/await:
describe('Utils async', function() {
it('должен корректно складывать числа асинхронно', async function() {
const result = await utils.addAsync(2, 3);
assert.strictEqual(result, 5);
});
});
В каждом из этих примеров Mocha будет корректно обрабатывать асинхронные операции и ожидать их завершения до того, как тест будет завершён.
Использование CommonJS в Mocha предоставляет мощный инструмент для
организации тестов и упрощения работы с большим количеством тестов и
вспомогательных функций. Разделение кода на модули, использование
экспорта и импорта позволяет сделать тесты более читаемыми и
поддерживаемыми. Mocha поддерживает работу с асинхронными тестами, что
даёт возможность тестировать асинхронные функции и логику с
использованием различных методов, таких как коллбеки, промисы и
async/await.