Написание тестов для приложения — самый сложный, но необходимый элемент процесса разработки. Тесты обеспечивают правильное сопровождение кода и улучшают его качество.
В этом руководстве мы покажем лучший способ обработки побочных эффектов в ваших приложениях Node.js.
Но сначала давайте дадим определение побочных эффектов.
- Что такое побочные эффекты?
- Тесты API и инициирование побочных эффектов
- Что такое библиотека побочных эффектов?
- Зачем использовать побочные эффекты для вашего приложения Node.js?
- Предварительные условия
- Настройка Typescript
- Настройка сервера Node.js
- Создание побочных эффектов
- Создание маршрутов API
- Тестирование API для вашего приложения Node.js
- Подведение итогов: Тестирование вашего приложения Node.js с помощью побочных эффектов
Что такое побочные эффекты?
Хотя часто хорошей идеей является сделать ваш код как можно более свободным от побочных эффектов, написание кода с побочными эффектами неизбежно в большинстве проектов.
В программировании считается, что функция или выражение имеет побочный эффект, если она использует или изменяет состояние за пределами своей области применения, например:
- чтение/запись данных в файл
- выполнение сетевого запроса к API
- вызов другой функции с побочным эффектом
Из-за этого результат вызова функции с побочными эффектами недетерминирован. Это усложняет тестирование функции по сравнению с тестированием функции, которая дает тот же результат при тех же входных данных и не изменяет состояние за пределами своей области действия.
Тесты API и инициирование побочных эффектов
Тесты API оценивают надежность, функциональность, производительность и безопасность приложения. Для выполнения этих тестов требуется три шага:
- Отправить запрос с необходимыми входными данными.
- Получить ответ.
- Проверить, что ответ вернул ожидаемый результат.
В каждом приложении есть сервер, который отвечает на эти запросы, что может вызвать побочные эффекты на внешней или внутренней части вашего приложения (путем выполнения вызовов API на сервер или чтения и записи в файл/базу данных).
Традиционно, чтобы справиться с этими побочными эффектами, вам приходилось имитировать действия ввода-вывода (Input/Output), регулярно изменяя свой код, чтобы заменить ввод-вывод кодом-заглушкой.
Но есть лучший способ: использовать библиотеку побочных эффектов!
Что такое библиотека побочных эффектов?
Библиотека побочных эффектов — это библиотека Javascript, которая позволяет записывать все побочные эффекты в одно место и загружать реальное/заглушечное поведение во время выполнения.
Зачем использовать побочные эффекты для вашего приложения Node.js?
Есть несколько преимуществ использования библиотеки побочных эффектов для тестирования вашего приложения Node.js:
- Она позволяет вам определить побочные эффекты каждой операции в вашем приложении.
- Вам не нужно иметь дело с имитатором API или регулярно настраивать его.
- У вас есть единое место, где хранятся все побочные эффекты вашего приложения (в терминологии DDD это слой инфраструктуры).
- Вашу программу будет легко тестировать.
- Вы создаете документацию для побочных эффектов вашего приложения, создавая файл побочных эффектов.
Предварительные условия
Прежде чем начать работу с этим учебником, убедитесь, что вы выполнили следующие требования:
- У вас установлен Node.js
- У вас установлен Postman
- У вас есть предварительные знания о Typescript
Настройка Typescript
Чтобы продемонстрировать, как можно использовать побочные эффекты в приложении, мы создадим сервер Node.js, который будет работать с приложением todo и создавать побочные эффекты для приложения.
Мы начнем с настройки Typescript для проекта. Установите Typescript глобально с помощью команды ниже:
npm install -g typescript
Затем создайте папку проекта и файл tsconfig.json
для конфигурации Typescript с помощью команд ниже:
mkdir side-effect-demo && cd side-effect-demo
tsc --init
Теперь замените содержимое файла tsconfig.json
следующими конфигурациями.
{
"compilerOptions": {
"target": "es2015", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"module": "commonjs", /* Specify what module code is generated. */
"rootDir": "./", /* Specify the root folder within your source files. */
"outDir": "./dist", /* Specify an output folder for all emitted files. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
"strict": true, /* Enable all strict type-checking options. */
"skipLibCheck": true,
},
}
Настройка сервера Node.js
Когда Typescript настроен для проекта, мы инициализируем проект Node.js с помощью команды ниже.
npm init -y
Приведенная выше команда создаст файл package.json
для хранения зависимостей вашего проекта. Теперь установите необходимые зависимости и devDependencies командой ниже:
npm i express side-effect-js && npm i -D typescript tsc ts-node-dev @types/express @types/node
После завершения установки создайте файл index.ts
. Обновите script
в файле package.json
со следующими конфигурациями.
"scripts": {
"dev": "ts-node-dev --clear index.ts",
"build": "tsc",
"start": "node dist/index.js"
},
Теперь создайте Express-сервер в файле index.ts
с помощью приведенного ниже фрагмента кода:
import express, { Express } from "express";
const app: Express = express();
app.listen(3000, () => {
console.log("Server is running on port 3000");
});
Затем выполните эту команду в терминале, чтобы запустить сервер.
npm run dev
Это позволит запустить сервер в режиме разработки и включить горячую перезагрузку для отражения последних изменений в приложении.
Создание побочных эффектов
Сейчас мы должны создать бизнес-логику для приложения. Но вместо метода MVC мы воспользуемся методом побочных эффектов. Для этого создайте новый файл side-effect.ts
в корневом каталоге вашего проекта. Добавьте этот фрагмент кода в файл side-effect.ts
.
import SideEffectJS from "side-effect-js";
const todos = [
{
id: 1,
text: "Learn JavaScript",
completed: true,
},
{
id: 2,
text: "Learn React",
completed: false,
},
{
id: 3,
text: "Learn Redux",
completed: false,
},
];
type Todos = {
id: number,
text: string,
completed: boolean,
};
В приведенном выше фрагменте кода мы импортируем SideEffectJS
, создаем фиктивные данные todos и тип Todos
, который будет служить моделью для todos.
Теперь давайте создадим побочный эффект, получим и создадим todo. Каждый побочный эффект имеет реальную функцию, имитационную функцию и идентификатор. id должен быть уникальным для каждого побочного эффекта.
//all todos
const getTodosReal = (): Todos[] => {
return todos;
}
const getTodoMock = (): Todos[] => {
return todos
}
//create Todo
const addTodoReal = (todo: Todos): Todos[] => {
todos.push(todo);
return todos;
}
const addTodoMock = (todo: Todos): Todos[] => {
todos.push(todo);
return todos;
}
const AllTodos = SideEffectJS.CreateEffectTyped<Todos, Todos[]>('all-todos', getTodosReal, getTodoMock);
const AddTodo = SideEffectJS.CreateEffectTyped<Todos, Todos[]>('add-todo', addTodoReal, addTodoMock);
export default [AllTodos, AddTodo];
Здесь мы создаем реальную и макетную функции для получения и создания todo. Затем мы используем CreateEffectTyped
для создания побочных эффектов для функций. Мы также указываем типы T
и R
в методе CreateEffectTyped
— макетная и реальная функции получают (T)
, а ожидаемые результаты для макетной и реальной функции (R)
. Наконец, мы экспортируем побочные эффекты.
Создание маршрутов API
Теперь, когда мы создали побочные эффекты для приложения, давайте определим маршруты API для их использования. Сначала нам нужно импортировать модуль побочных эффектов и только что созданные побочные эффекты в наш корневой файл index.ts
.
...
import SideEffectJS from "side-effect-js";
import sideEffect from "./side-effect";
Затем нам нужно загрузить наши побочные эффекты, получить побочные эффекты, используя их соответствующие идентификаторы, и присвоить их переменной.
...
SideEffectJS.Load(sideEffect);
const getTodos = SideEffectJS.Get('all-todos');
const createTodo = SideEffectJS.Get('add-todo');
Далее нам нужно определить два маршрута API и вызвать их с помощью приведенного ниже фрагмента кода.
app.use(express.json());
app.get("/api/todo", async (req, res) => {
res.json({ data: await getTodos() });
});
app.post("/api/todo", async (req, res) => {
res.json({ data: await createTodo(req.body) });
});
Мы разбираем входящие JSON-запросы, помещаем разобранные данные в req
и определяем маршруты API.
Тестирование API для вашего приложения Node.js
Теперь, когда мы создали API для приложения, давайте протестируем его. Запустите Postman и отправьте GET-запрос на URL localhost:3000/api/todo
, чтобы получить тодосы.
Затем отправьте POST-запрос и добавьте в тело запроса следующие данные JSON.
{
"id":4,
"text":"Learn Python",
"completed":false
}
Подведение итогов: Тестирование вашего приложения Node.js с помощью побочных эффектов
В этом руководстве мы узнали, как протестировать приложение Node.js с помощью побочных эффектов. Мы начали с определения библиотеки побочных эффектов и рассказали о том, зачем ее использовать. Затем мы создали приложение todo.
Надеюсь, эта статья помогла вам понять, как лучше тестировать ваше приложение Node.js. Узнайте больше о побочных эффектах из документации.
До следующего раза, счастливого кодинга!
P.S. Если вам понравилась эта статья, подпишитесь на наш список JavaScript Sorcery для ежемесячного глубокого погружения в более волшебные советы и трюки JavaScript.
P.P.S. Если вам нужен APM для вашего Node.js приложения, обратите внимание на AppSignal APM для Node.js.