Автор оригинала: Allan Mogusu.
Вступление
Тестирование является фундаментальной частью процесса разработки программного обеспечения. При создании веб-приложений мы производим звонки в сторонние API, базы данных или другие услуги в нашей среде. Следовательно, наши тесты должны подтвердить эти запросы, отправляются и ответы обрабатываются правильно. Тем не менее, мы не всегда сможем общаться с этими внешними службами при запуске тестов.
На нашем компьютере для местных разработок у нас не может быть, чтобы ключевые API компании или учетные данные базы данных успешно запустить тест. Вот почему мы иногда «поддельные» отклики HTTP или баз данных с заглушка , обманывая наш код, чтобы вести себя как реальный запрос.
В этой статье мы начнем с взгляда на то, какие кломы и почему мы хотели бы использовать их. Затем мы будем использовать Sinon.js , популярная библиотека тестирования JavaScript, для создания модульных тестов для JavaScript, который заглушает HTTP-запрос.
Затем мы продолжим это со статьями на шпионах и издевателях:
- Использование заглушек для тестирования в JavaScript с Sinon.js ( Вы здесь )
- Использование шпионов для тестирования в JavaScript с Sinon.js
- Использование издеваний для тестирования в JavaScript с Sinon.js
Что такое заглушки?
Тестовая заглушка – это функция или объект, который заменяет фактическое поведение модуля с фиксированным ответом. Застройка может вернуть только фиксированный ответ, который он был запрограммирован на возврат.
Ступени можно рассматривать как предположение для нашего теста – если мы предположим, что внешняя служба возвращает этот ответ, вот как функция будет вести себя.
Представьте, что у вас есть функция, которая принимает HTTP-запрос и получает данные с конечной точки GraphQL. Если мы не сможем подключиться к конечной точке GraphQL в наших тестах, мы бы заглушаем его ответ, чтобы наш код будет работать так, как если GraphQL фактически ударил. Наш код функции не знал бы разницы между реальным откликом GraphQL VS нашего непокрытого ответа.
Давайте посмотрим на сценарии, где stubbing полезен.
Зачем использовать заглушки?
Создавая запросы на внешние услуги в тесте, вы можете столкнуться с этими проблемами:
- Неспособность тестов из-за ошибок подключения к сети вместо ошибок кода
- Длительное время запуска, так как сетевое задержка добавляет время тестирования
- Ошибочно влияет на производственные данные с тестами, если возникает ошибка конфигурации
Мы можем обойти эти проблемы, изолируя наши тесты и острубив эти внешние звонки. Не было бы сетевой зависимости, создавая наши тесты более предсказуемыми и менее вероятными неудачными. Без задержки сети наши тесты, как ожидается, также будут быстрее.
Есть сценарии, где внешние запросы не будут работать. Например, в процессах создания CI/CD распространены для блокировки внешних запросов при запуске тестов по соображениям безопасности. Также вероятно, что когда-нибудь мы напишем код, который зависит от службы, который все еще находится в разработке, а не в состоянии, который будет использоваться.
В этих случаях заглушки очень полезны, поскольку она позволяет нам проверить наш код, даже когда служба недоступна.
Теперь, когда мы знаем, какие кломы и почему они полезны, давайте использовать Sinon.js, чтобы получить практический опыт работы с заглушками.
Использование Sinon.js, чтобы создать заглушку
Мы будем использовать Sinon.js, чтобы заглушить ответ от API JSON, который извлекает список фотографий в альбоме. Наши тесты будут созданы с Моча и Чай тестирование библиотек. Если вы хотите узнать больше о тестировании с Mocha и Chai, прежде чем продолжить, вы можете следовать Наше гид Отказ
Настраивать
Во-первых, в вашем терминале создайте новую папку и переместитесь в него:
$ mkdir PhotoAlbum $ cd PhotoAlbum
Инициализировать NPM, чтобы вы могли отслеживать установку пакетов:
$ npm init -y
Как только это завершено, мы можем начать устанавливать наши зависимости. Во-первых, давайте установим библиотеку запроса, которая будет использоваться нашим кодом для создания HTTP-запроса к API. В вашем терминале введите:
$ npm i request --save
Теперь давайте установим все тестовые библиотеки в виде зависимостей Dev. Тестовый код не используется в производстве, поэтому мы не устанавливаем библиотеки тестирования в качестве регулярных кодовых зависимостей с --save
вариант. Вместо этого мы будем использовать --save-dev
Возможность сказать NPM, что эти зависимости следует использовать только в нашей среде разработки/тестирования. Введите команду в вашем терминале:
$ npm i mocha chai sinon --save-dev
Со всеми нашими библиотеками импортируем, мы создадим новый index.js
Файл и добавьте код, чтобы сделать запрос API там. Вы можете использовать терминал, чтобы создать index.js
файл:
$ touch index.js
В вашем текстовом редакторе или IDE напишите код ниже:
const request = require('request'); const getPhotosByAlbumId = (id) => { const requestUrl = `https://jsonplaceholder.typicode.com/albums/${id}/photos?_limit=3`; return new Promise((resolve, reject) => { request.get(requestUrl, (err, res, body) => { if (err) { return reject(err); } resolve(JSON.parse(body)); }); }); }; module.exports = getPhotosByAlbumId;
Эта функция делает вызов API, который возвращает список фотографий из альбома, идентификатор которого передается как параметр на функцию. Мы ограничиваем ответ, чтобы вернуть только три фотографии.
Теперь мы напишем тесты на нашу функцию, чтобы подтвердить, что она работает как ожидалось. Наш первый тест не будет использовать заглушки, но вместо этого он сделает фактический запрос.
Тестирование без загрязнений
Во-первых, давайте создадим файл, чтобы написать наши тесты. В терминале или иначе сделать index.test.js
Файл в текущем каталоге:
$ touch index.test.js
Наш код проверит, что мы вернемся на три фотографии, и что каждая фотография имеет ожидаемую ID
, Название
и URL
характеристики.
В index.test.js
Файл, добавьте следующий код:
const expect = require('chai').expect; const getPhotosByAlbumId = require('./index'); describe('withoutStub: getPhotosByAlbumId', () => { it('should getPhotosByAlbumId', (done) => { getPhotosByAlbumId(1).then((photos) => { expect(photos.length).to.equal(3); photos.forEach(photo => { expect(photo).to.have.property('id'); expect(photo).to.have.property('title'); expect(photo).to.have.property('url'); }); done(); }); }); });
В этом тесте мы сначала требуем Ожидайте ()
Функция от Chai, а затем требуется getphotosbyalbumid ()
Функция от нашего index.js
файл.
Мы используем Mocha Опишите ()
и Это ()
функции, чтобы мы могли использовать моча
Команда для запуска кода в качестве теста.
Перед запуском нашего теста нам нужно добавить скрипт на наш Package.json, чтобы запустить наши тесты. В Package.json
Файл, добавьте следующее:
"scripts": { "test": "mocha index.test.js" }
Теперь запустите тест со следующей командой:
$ npm test
Вы должны увидеть этот выход:
$ mocha index.test.js withoutStub: getPhotosByAlbumId ✓ should getPhotosByAlbumId (311ms) 1 passing (326ms)
В этом случае тест занял 326 мс, однако это может варьироваться в зависимости от вашей скорости и местоположения Интернета.
Этот тест не пройдет, если у вас нет активного подключения к Интернету, так как HTTP-запрос не удался. Хотя это не означает, что функция не ведет себя, как и ожидалось. Давайте использовать заглушку, чтобы мы могли проверить поведение нашей функции без сетевой зависимости.
Тестирование с заглушками
Давайте переписаним нашу функцию, чтобы мы заглушаем запрос на API, возвращая предопределенный список фотографий:
const expect = require('chai').expect; const request = require('request'); const sinon = require('sinon'); const getPhotosByAlbumId = require('./index'); describe('with Stub: getPhotosByAlbumId', () => { before(() => { sinon.stub(request, 'get') .yields(null, null, JSON.stringify([ { "albumId": 1, "id": 1, "title": "accusamus beatae ad facilis cum similique qui sunt", "url": "https://via.placeholder.com/600/92c952", "thumbnailUrl": "https://via.placeholder.com/150/92c952" }, { "albumId": 1, "id": 2, "title": "reprehenderit est deserunt velit ipsam", "url": "https://via.placeholder.com/600/771796", "thumbnailUrl": "https://via.placeholder.com/150/771796" }, { "albumId": 1, "id": 3, "title": "officia porro iure quia iusto qui ipsa ut modi", "url": "https://via.placeholder.com/600/24f355", "thumbnailUrl": "https://via.placeholder.com/150/24f355" } ])); }); after(() => { request.get.restore(); }); it('should getPhotosByAlbumId', (done) => { getPhotosByAlbumId(1).then((photos) => { expect(photos.length).to.equal(3); photos.forEach(photo => { expect(photo).to.have.property('id'); expect(photo).to.have.property('title'); expect(photo).to.have.property('url'); }); done(); }); }); });
Перед запуском теста мы говорим Sinon.js, чтобы заглушить Получить ()
Функция Запрос
объект, который используется в getphotosbyalbumid ()
Отказ
Аргументы прошли к Урожайность ()
Функция заглушки – это аргументы, которые будут переданы обратным вызова запроса на получение. Мы проходим null
для Err
и res
Параметры и массив фальшивых фотоальбомов для Тело
параметр.
Примечание : после ()
Функция выполняется после завершения теста. В этом случае мы восстановим поведение Запрос
Библиотека Получить ()
функция. Лучшие практики побуждают наши тестовые состояния быть независимыми для каждого теста. Восстанавливая функцию, изменения, которые мы сделали для этого теста, не повлияют на то, как она используется в других тестах.
Как и раньше, мы запускаем этот тест с NPM Test
Отказ Вы должны увидеть следующий вывод:
$ mocha index.test.js with Stub: getPhotosByAlbumId ✓ should getPhotosByAlbumId 1 passing (37ms)
Большой! Теперь без подключения к Интернету мы все еще уверены, что наша функция хорошо работает с ожидаемыми данными. Тест бежал быстрее, а также! Без сетевого запроса нам просто нужно получить данные из памяти.
Заключение
Застройка – это замена функции, которая возвращает фиксированные данные при вызовах. Мы обычно заглушним запросы на внешние системы, чтобы пройти тесты более предсказуемыми и устранить необходимость в сетевых соединениях.
Sinon.js можно использовать вместе с другими функциями тестирования к функциям заглушки. В этой статье мы ограбили HTTP Get Communit, поэтому наш тест может работать без подключения к Интернету. Это также сократило время теста.
Если вы хотите увидеть код для этого руководства, вы можете найти его здесь Отказ
В нашей следующей статье мы продолжаем с Sinon.js и охватываем, как использовать шпики для тестирования JavaScript.