Этот пост в одной из частей моей серии о Создание реальных API с помощью NodeJS для начинающих.
Все основное содержание этой серии на случай, если мы хотим быстро ориентироваться:
- От анализа предметной области до разработки моделей баз данных.
- Настроить проект узла с нуля.
- Использование Sequelize и образа MySQL Docker для разработки.
- Организуйте структуру проекта.
- Аутентификация API с помощью паспорта.
- Написание модульного теста для API NodeJS с помощью Jest framework.
- Dockerize NodeJS application.
Все эти коды в этом проекте можно найти здесь.
Когда я исследовал, как писать модульные тесты для API в NodeJS, в большинстве статей, которые я обнаружил, упоминается, как их реализовать с помощью Mocha, Chai, istanbul и т. Д. ... Немного обсуждаются темы о Jest framework, одном из самых известных и популярных инструментов. надежная среда тестирования от Facebook. Если мы сможем интегрировать Jest в наш проект, нам не нужно будет объединять несколько библиотек, указанных выше. Jest имеет встроенную поддержку функций для тестирования снимков, сопоставлений и покрытия.
Еще одна вещь в этом разделе: мы не будем имитировать нашу базу данных. Вместо этого мы запустим тесты с тестом базы данных. Конечно, мы можем имитировать базу данных для более простого решения. Однако мы постараемся немного усерднее, чем обычно, чтобы увидеть, могут ли все эти вещи работать хорошо или нет.
Требовать пакеты
jest
: конечно, наш основной пакет в этом разделеsupertest
: мы собираемся протестировать все наши контроллеры, поэтому этот пакет выглядит как абстракция высокого уровня для тестирования HTTP.supertest-as-promise
: как и обещано, нагнетаетsupertest
методомthen
. Подробности можно посмотреть здесь.
Настройка Jest
Установить пакет jest
через npm
$ npm install --save-dev jest supertest supertest-as-promise
Измените package.json следующим образом
{ "scripts": { "start": "nodemon ./app.js", "pretest": "NODE_ENV=test ./node_modules/.bin/sequelize db:create && ./node_modules/.bin/sequelize db:migrate ", "test": "NODE_ENV=test jest --testPathPattern='./tests/.*\\.test\\.js$' --detectOpenHandles --runInBand --forceExit" }, ... "devDependencies": { "jest": "^23.6.0", "supertest": "^3.3.0", "supertest-as-promised": "^4.0.2" }, "jest": { "setupTestFrameworkScriptFile": "<rootDir>/config/jest/setup.js" } }
Посмотрите подробности test
внутри scripts
Тестовый сценарий
"scripts": { "test": "NODE_ENV=test jest --testPathPattern='./tests/.*\\.test\\.js$' --detectOpenHandles --runInBand --forceExit" }
NODE_ENV=test
настроить среду узла наtest
.--testPathPattern='./tests/.*\\.test\\.js$'
мы запустим тест для всех файлов с именем, включаяtest
внутриtests
папки. Например, имя файлаtask.controller.test.js
--detectOpenHandles
одна дополнительная опция для сбора и печати открытых дескрипторов, препятствующих чистому завершению Jest.--runInBand
важная опция! Мы собираемся запустить тест с тестом базы данных, а не издеваться над ним. Это гарантирует, что Jest будет выполнять наши тесты не параллельно, а последовательно. Параллельное выполнение тестов может привести к проблемам чтения / записи в нашей базе данных.--forceExit
помогает выйти из Jest, если он не может выйти после завершения всех тестов.
"scripts": { "pretest": "NODE_ENV=test ./node_modules/.bin/sequelize db:create && ./node_modules/.bin/sequelize db:migrate " }
pretest
означает, что он будет запущен до того, как мы запустим сценарий test
. Внутри prescript
скрипта мы хотим инициализировать наш тест базы данных.
"jest": { "setupTestFrameworkScriptFile": "<rootDir>/config/jest/setup.js" }
setupTestFrameworkScriptFile
ссылка на один файл будет вызываться для выполнения перед каждым тестом (как Jest-документ). Перед запуском нового тестового примера мы добавим кое-что, например, базу данных установки или очистки.
Внутри файла /config/jest/setup.js
мы хотим очистить наш тест базы данных перед запуском одного нового теста. Это помогает нашему тесту быть более согласованным с чистой базой данных.
Структура теста
Я создаю новую папку tests
внутри нашего корневого проекта. В эту папку мы поместим все тесты файлов и помощников по тестированию.
Давайте посмотрим на один пример написания тестов для пользовательского контроллера.
Все эти коды здесь вполне понятны. Если мы хотим создать нового пользователя, мы отправим POST
запрос с содержанием name
и password
значений /v1/users
конечной точке API. У нас есть testHelpers.withLogin
метод, который поможет нам отправить запрос с проверкой подлинности.
Похоже на то, чтобы получить всех пользователей в нашем приложении. Мы отправим аутентифицированный запрос GET на /v1/users
конечную точку API. testHelpers.generateUsers()
вначале сформирует для нас список пользователей.
Все тесты для остальных контроллеров такие же. Подробности можно посмотреть в репозитории проекта.
В настоящее время наш проект может без проблем стартовать в нашем локальном. Следующий шаг - это волнение, когда мы запускаем наш продукт. Увидимся там.
Не стесняйтесь хлопать в ладоши, если вы считаете, что это стоит прочитать!
~ Удачного кодирования с мистером Лео ~