Автор оригинала: Allan Mogusu.
Вступление
Тестовые mock-обьекты – это объекты, которые заменяют реальные объекты при моделировании их функций. Mock также имеет ожидания о том, как будут использоваться тестируемые функции.
В некоторых тестовых случаях модуля мы можем захотеть объединить функциональные возможности шпионов, наблюдать за поведением метода по вызову, а затем заглушки, чтобы заменить функциональность метода, в обеспечении того, чтобы мы не сделаем фактический вызов функции, но все еще могут Соответственно следить за поведением нашей целевой функции. В таком случае мы можем использовать mock-обьекты.
В этой статье мы будем стремиться понять, какие mock есть и как их использовать в модульных тестах. Затем мы получим опыт работы с Sinon.js Чтобы издеваться на HTTP-запрос.
Эта статья является третью нашей серии по методам тестирования подразделений с Sinon.js. Мы рекомендуем вам прочитать наши предыдущие статьи на эту тему, а также:
- Использование заглушек для тестирования в JavaScript с Sinon.js
- Использование шпионов для тестирования в JavaScript с Sinon.js
- Использование моков для тестирования в JavaScript с Sinon.js ( Вы здесь )
Что такое макеты?
Макеты объединяют функциональность обоих Шпионы и заглушки , что означает, что они заменяют целевую функцию, но в то же время предоставляют нам возможность наблюдать, как названа функция.
Кроме того, макеты имеют встроенные утверждения, называемые ожиданиями. Вы определяете ожидания того, как ваша издевалась функция будет использоваться авансом. Если ваш издеватель не удовлетворил свои ожидания, ваш тест потерпит неудачу.
Например, рассмотрим функцию, которая связывается с базой данных для сохранения деталей контакта. С помощью макета вместо настоящей базы данных наша функция будет ударять поддельную базу данных. Мы можем определить, какой ответ он даст. Мы также заявляем, сколько раз база данных должна называться и аргументы его следует назвать.
Наконец, как часть теста, мы подтверждаем, что наша база данных Mock называлась точным количеством времени, которые мы ожидали. Мы также проверяем, что он вызвал только аргументы, которые наша функция должна ее предоставить.
Увидев, какие издевательства, давайте теперь будем смотреть на ситуации, когда мы можем их нанять.
Зачем использовать mock-объекты?
Макеты полезны при проверке того, как используется внешняя зависимость в функции. Используйте издевательства, когда вы заинтересованы в:
- Подтверждение того, что ваша внешняя зависимость используется вообще
- Проверка того, что ваша внешняя зависимость используется правильно
- Обеспечение того, чтобы ваша функция может обрабатывать разные ответы от внешних зависимостей.
Представьте, что вы тестируете функцию, которая говорит с третьей стороной API, чтобы получить некоторые пользовательские данные. Чтобы сделать запросы к внешнему API, вам нужно сделать несколько звонков для аутентификации первым. Уже становится неудобным для использования настоящих API в тестах. Кроме того, у вас может не всегда иметь подключение к Интернету для доступа к API при запуске тестов.
С макетом мы вернем поддельные ответы. Теперь мы можем быстро проверить, что наша функция ведет себя правильно, когда дает поддельные данные в определенном формате. Мы также узнаем, что наша функция выполнила запросы на API с правильными параметрами.
Давайте теперь посмотрим, как мы можем использовать Sinon.js для создания издеваний.
Использование Sinon.js для создания издевательства
Мы будем использовать Sinon.js, чтобы изменить ответ от API JSON, который извлекает список фотографий в альбоме. В дополнение к Sinon.js мы будем использовать Моча и Чай настроить и запустить тесты. Вы можете прочитать наше руководство Наше гид узнать больше о них, прежде чем продолжить.
Настраивать
Создайте каталог под названием Синонмик
и перейти к нему:
$ mkdir SinonMock $ cd SinonMock
Затем мы будем использовать NPM для инициализации проекта для отслеживания файлов проекта, которые мы создаем:
$ npm init -y
Далее мы установим Mocha и Chai в качестве тестирования зависимостей для проведения наших тестов, а также Sinon.js:
$ npm i mocha chai sinon --save-dev
Заполнив нашу настройку, давайте посмотрим HTTP-запрос.
Издевающийся http call с sinon.js
В нашей предыдущей статье на тестовых шпионах мы держились на HTTP-запросе на API фотоальбома. Мы продолжим с этим примером для этой статьи.
Создайте файл в корне Синонмик
каталог и называть это index.js
:
$ touch index.js
В созданном файле введите следующий код:
const request = require('request'); module.exports = { getAlbumById: async function(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)); }); }); } };
Рекомендовать, getAlbumbyId ()
Это функция, которая вызывает API JSON, которая возвращает список фотографий. Мы предоставляем идентификатор альбома в качестве аргумента функций. Ранее мы изучали острубингу и шпионить по request.get ()
метод.
Теперь мы будем высмеивать Запрос
Объект и проверьте, если Получить ()
Метод называется один раз, по мере необходимости, и подтвердите, если он получил правильные аргументы. Затем мы проверим, что наша функция имеет правильные свойства на основе того, что было возвращено из нашего издевания.
Создайте другой файл в корне Синонмик
каталог и называть это index.test.js
:
$ touch index.test.js
Открыть index.test.js
Файл с редактором и введите следующий код:
const expect = require('chai').expect; const request = require('request'); const sinon = require('sinon'); const index = require('./index'); describe('with mock: getPhotosByAlbumId', () => { it('should getPhotosByAlbumId', (done) => { let requestMock = sinon.mock(request); const myPhotos = [{ "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" }]; requestMock.expects("get") .once() .withArgs('https://jsonplaceholder.typicode.com/albums/2/photos?_limit=3') .yields(null, null, JSON.stringify(myPhotos)); index.getAlbumById(2).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'); }); requestMock.verify(); requestMock.restore(); done(); }); }); });
В нашем тестовом случае мы впервые создаем макет Запрос
Объект, использующий Sinon.Mock ()
и назвать это Requestmock
Отказ Requestmock
Объект имеет функции Запрос
объект, но функции ничего не делают по умолчанию.
После подачи некоторых фиксированных данных, мы переопределяем оригинал Получить ()
Метод объекта запроса с использованием Mock API Sinon.js Ожидайте ()
Ожидайте ()
Метод принимает в одном аргументе, который является методом издеватого объекта, который мы ожидаем, будет использоваться.
один раз ()
Метод утверждает, что наше ожидание называется один раз. В этом случае Получить ()
Метод объекта запроса будет называться ровно один раз.
asargs ()
Метод утверждает, что мы ожидаем, что Получить ()
Способ быть вызванным с массивом аргументов, которые мы его поставляем. В нашем случае URL API.
Урожайность ()
Метод ставит данные в обратный вызов, что наш Mock Object принимает. В этом случае наша ошибка и ответ оба null
Но наше тело имеет ответ JSON.
После этой настройки мы тогда называем наши getAlbumbyId ()
Способ и проверьте, если фотографии вернулись, имеют правильные свойства.
Обратите внимание на Проверьте ()
Звонок Requestmock
объект, чтобы подтвердить, что наши ожидания были выполнены. Если ожидания потерпят неудачу, тест бросит исключение. Затем мы называем Восстановить ()
Способ отказаться от макета, созданного нашим тестом и восстановить оригинальный объект запроса.
Когда вы запускаете этот тест, вы должны получить следующий результат:
$ mocha index.test.js with mock: getPhotosByAlbumId ✓ should getPhotosByAlbumId 1 passing (13ms) ✨ Done in 0.72s.
Чтобы подтвердить поведение нашего издевательства, давайте посмотрим, не удается ли ожидания, если мы изменим URL, с которым мы общаемся. В вашем index.js
Файл, изменить:
const requestUrl = `https://jsonplaceholder.typicode.com/albums/${id}/photos?_limit=3`;
К:
const requestUrl = `https://example.com`;
Теперь запустите тесты еще раз:
$ mocha index.test.js
Так как мы поменяли вход в Получить ()
Метод, аргумент URL больше не совпадает с тем, что в нашем тесте. Мы получим этот вывод, когда мы запустим тест:
> mocha index.test.js with mock: getPhotosByAlbumId (node:85434) UnhandledPromiseRejectionWarning: ExpectationError: Unexpected call: get(https://example.com, function () {}) Expected get(https://jsonplaceholder.typicode.com/albums/2/photos?_limit=3[, ...]) once (never called)
Большой! Мы довольно уверены, что наши издеватели гарантируют, что наша функция ведет себя так, как мы ожидаем!
Используя издевательства, мы смогли получить преимущества как шпионов и заглушек. Мы смогли проверить, что наша функция была названа ровно один раз, и с правильными аргументами выгода предоставлена нам шпионов. Мы также смогли заглушить запрос, чтобы мы не сделали фактический HTTP-вызов на API, что гарантировало, что наш тест работает быстро.
Заключение
Макеты в тестировании подразделения объединяют функциональные возможности как шпионов, так и заглушек, заменяя функции, такие как заглушки, и в то же время обеспечивая нам средства для наблюдения за функциями для проверки того, как их называли, функциональность предоставила нас шпионами. Затем издеватели дают нам преимущество подтверждения того, как использовалась наша функция в тесте.
В этой статье мы представили концепцию издевательства в тестировании подразделения и увидели, как мы могли бы издеваться на HTTP Call. Чтобы узнать больше о Sinon.js Mocks, вы можете просмотреть Официальная документация из макетов API.