Четкое и краткое введение в тестирование Коа с помощью Jest и Supertest

  1. Требования
  2. Настройка проекта
  3. Настройка Jest и Supertest
  4. Настройка вашего первого теста
  5. Настройка коа
  6. Тестирование объекта с помощью toHaveProperty
  7. Куда пойти отсюда
Кредит Фотографии: Wikimedia Commons

Mocha и Chai - это путь, когда дело доходит до тестирования Node API, но я не удержался, чтобы дать Jest попробовать.

Для веб-разработчика важно быть довольным собственным кодом. Но вы также должны подготовиться к тому, чтобы подвергать сомнению свои собственные подходы.

Это еще более верно в отношении земли Javascript: сцена меняется так быстро! Иногда этот новый модный инструмент стоит посмотреть, иногда нет. А также Шутка попадает в первую категорию.

Требования

Чтобы следовать, у вас должно быть базовое понимание Javascript и ES6.

Также убедитесь, что у вас установлена ​​одна из последних версий Node. В следующем посте я буду использовать асинхронная / Await шаблон, введенный в Узел 7.6.0.

Настройка проекта

Чтобы запустить проект, создайте пустой каталог с именем jest-koa2:

MKDIR JEST-KOA2

затем перейдите внутрь:

cd jest-koa2

и инициализировать package.json, выполнив:

npm init -y

Флаг -y настраивает package.json со значениями по умолчанию, а не задает нам какие-либо вопросы.

Нам также необходимо создать некоторую структуру каталогов. В вашем терминале введите:

mkdir {тест, сервер}

и нажмите ввод.

Настройка Jest и Supertest

Jest позиционирует себя как «восхитительный». Это должно быть правдой, потому что многие люди счастливы после перехода из Мокко.

Фреймворк для тестирования Facebook создан для тестирования React. Он также поддерживает Node, поэтому подходит для тестирования как веб-интерфейса, так и внешнего интерфейса.

Установите пакет с помощью:

нпм я шучу - спас-дев

затем обновите раздел скрипта внутри package.json . Команда test должна указывать на исполняемый файл Jest, а среда тестирования должна указывать на узел:

"scripts": {"test": "jest"}, "jest": {"testEnvironment": "node"}

Jest - это среда тестирования , она предоставляет платформу для автоматического тестирования вместе с базовой библиотекой утверждений (Expect). Для тестирования API вы все равно должны полагаться на некоторые внешние зависимости: я выбрал Supertest главным образом потому, что он поддерживает обещания, плюс он легкий. (Кстати, Expect недавно был передан команде Jest).

Установить супертест с:

нпм я супер-тест

и ты готов к работе.

Настройка вашего первого теста

Создайте новый файл с именем index.routes.test.js в тестовом каталоге:

// Требуется сервер Koa const server = require ("../ server / index"); // требовать супертест const request = require ("supertest"); // закрываем сервер после каждого теста afterEach (() => {server.close ();}); Описание ("маршруты: индекс", () => {тест ("должен отвечать, как ожидалось", async () => {const response = запрос ожидания (сервер) .get ("/"); ожидание (response.status) .toEqual (200); ожидание (response.type) .toEqual ("application / json"); ожидание (response.body.data) .toEqual ("Отправка некоторого JSON");});});

В приведенном выше коде я тестирую базовую конечную точку API, поскольку это может быть корневой маршрут /.

Я предполагаю, что:

  • сервер отвечает ожидаемым кодом состояния
// ... ожидаем (response.status) .toEqual (200); // ...
  • сервер отвечает верным JSON
// ... Ожидаем (response.type) .toEqual ("application / json"); // ...
  • сервер возвращает данные, как и ожидалось
// ... Ожидаем (response.body.data) .toEqual ("Отправка некоторого JSON"); // ...

Что более важно, я могу использовать async / await внутри тестового блока:

// ... description ("rout: index", () => {test ("должен отвечать как положено", async () => {const response = await request (server) .get ("/"); / /});}); // ...

Обратите внимание, что async / await не уникален для Jest. Если вы запустите хотя бы Node 7.6.0, тот же шаблон может работать и с Мокко и чай ,

ПРИМЕЧАНИЕ : вы также можете использовать блок it () вместо test ()

С первым тестом на месте запустите:

npm run test

заставить его потерпеть неудачу:

FAIL test / index.routes.test.js ● Не удалось запустить набор тестов. Не удается найти модуль '../server/index' из 'index.routes.test.js' в Resolver.resolveModule (node_modules / jest-resol / build / / index.js: 192: 17) в Object. <anonymous> (test / index.routes.test.js: 1: 105) Наборы тестов: 1 провал, 1 всего тестов: 0 всего моментальных снимков: 0 всего времени: 0,612 с все тестовые наборы.

Теперь все, что нам нужно сделать, - это создать базовый сервер Koa для прохождения теста.

Первое правило TDD: написать тест и заставить его провалиться

Для сравнения, вот как выглядит тот же тест в Mocha / Chai / Chai-Http. (Я опустил проверку ошибок в версии Jest):

const chai = require ("chai"); const should = chai.should (); const chaiHttp = require ("chai-http"); chai.use (chaiHttp); описывает ("маршруты: индекс", () => {это ("должен ответить как ожидалось", сделано => {chai .request (сервер) .get ('/') .end ((err, res) => { should.not.exist (err); res.status.should.eql (200); res.type.should.eql ("application / json"); res.body.data.eql ("Отправка некоторого JSON") сделано ();});});});

Это немного более многословно и не использует async / await.

Вернуться на сервер сейчас!

Настройка коа

Коа веб-фреймворк для Node.js, созданный теми же разработчиками экспресс ,

В отличие от Express, Коа был рожден с учетом минимализма: он охватывает только наименьшее возможное. Это даже не включает маршрутизатор! Некоторые другие замечательные функции:

  • возможность использовать async / await из коробки
  • контекст , объект, содержащий объекты запроса и ответа Node.js. Он специфичен для Коа и предоставляет множество удобных методов

Давайте продолжим, установив Koa вместе с роутером:

нпм и коа коао-роутер

Затем создайте новый файл с именем index.js внутри каталога server /:

const Koa = require ("коа"); const Router = require ("koa-router"); const router = новый маршрутизатор (); const app = new Koa (); const PORT = process.env.PORT || 8081; router.get ("/", async ctx => {ctx.body = {data: "Отправка некоторого JSON"};}); app.use (router.routes ()); const server = app.listen (PORT) .on ("error", err => {console.error (err);}); module.exports = server;

Этот простой сервер Koa ответит на / (корневой) маршрут. У него есть одно задание: отправка JSON-ответа пользователю. В нашем случае «пользователь» будет Jest. Это очень надуманный пример, но этого достаточно, чтобы пройти тест.

Запустите тестовый набор снова:

тест npm

и смотреть тестовый проход:

PASS test / index.routes.test.js маршруты: индекс ✓ должен отвечать, как и ожидалось (19 мс). Наборы тестов: 1 пройдено, 1 всего тестов: 1 пройдено, 1 всего снимков: 0 всего времени: 0,471 с, по оценкам 1 с Выполнить все тесты люкс. Второе правило TDD: напишите достаточно кода, чтобы пройти тест

Тестирование объекта с помощью toHaveProperty

Давайте немного расширим наш тест. Что если мы хотим проверить, содержит ли объект некоторые свойства или нет? toHaveProperty это именно то, что мы ищем!

Исходный тест можно переписать следующим образом:

// description ("rout: index", () => {test ("должен отвечать как положено", async () => {const response = await request (server) .get ("/"); ожидаем (ответ. status) .toEqual (200); ожидание (response.type) .toEqual ("application / json"); ожидание (response.body.data) .toEqual ("отправка некоторого JSON"); ожидание (response.body.person) .toHaveProperty ("name"); ожидаемо (response.body.person) .toHaveProperty ("lastname"); ожидаемо (response.body.person) .toHaveProperty ("role"); ожидаемо (response.body.person) .toHaveProperty ("возраст");});});

но у вышеприведенного подхода есть проблема: чем больше свойств вы тестируете, тем более загроможденным становится тест. Object.keys может сделать его более читабельным:

// description ("rout: index", () => {test ("должен отвечать как положено", async () => {const response = await request (server) .get ("/"); ожидаем (ответ. status) .toEqual (200); ожидание (response.type) .toEqual ("application / json"); ожидание (response.body.data) .toEqual ("отправка некоторого JSON"); ожидание (Object.keys (ответ. body.person)). toEqual (wait.arrayContained (["имя", "фамилия", "роль", "возраст"]));});});

Запустите тестовый набор снова:

тест npm

и смотреть это не получится

FAIL test / index.routes.test.js ● маршруты: индекс ›должны отвечать ожидаемым (объект) [. Не] .toHaveProperty (путь) Ожидаемый объект будет объектом. Получено: undefined: undefined в Object.test (test / index.routes.test.js: 14: 35) в <anonymous> в process._tickCallback (internal / process / next_tick.js: 188: 7) маршруты: индекс ✕ следует ответьте, как и ожидалось (20 мс). Наборы тестов: 1 не пройден, 1 всего тестов: 1 не пройден, 1 всего снимков: 0 всего: 0,433 с, по оценкам 1 с.

Чтобы пройти тест, мы должны добавить объект person в ctx.body внутри маршрута Koa.

Откройте файл server / index.js и примените исправление:

// router.get ("/", async ctx => {ctx.body = {data: "Отправка некоторого JSON", персона: {name: "Valentino", фамилия: "Gagliardi", роль: "Web Developer", возраст: 32}};}); //

Сохраните и закройте файл, затем снова запустите тест:

тест npm

и смотреть, как это проходит!

PASS test / index.routes.test.js маршруты: индекс ✓ должен отвечать, как и ожидалось (19 мс). Наборы тестов: 1 пройдено, 1 всего тестов: 1 пройдено, 1 всего снимков: 0 всего времени: 0,43 с, по оценкам 1 с. Выполнить все тесты люкс.

Хотите знать, каков следующий шаг? Копай глубже в шутку документация и начните писать свои собственные тесты!

Куда пойти отсюда

Вы заметили какую-либо ошибку в моем коде? Любое предложение? Я хотел бы услышать ваш вклад в комментариях ниже!

Я предлагаю следующие чтения, чтобы узнать больше о переходе от Мокко к Шуту: Разблокировка теста производительности - переход с Мокко на Jest а также Почему мы переносим юнит-тесты на Jest (и почему вы тоже должны )

Это все! Спасибо за чтение, увидимся в следующий раз!

Я Валентино Гальярди, и я помогаю занятым людям освоить этот безумный современный JavaScript-материал. Я занимаюсь обучением и консультированием по JavaScript, React, Redux.

Давайте свяжемся!

Хотите знать, каков следующий шаг?
Любое предложение?