Рубрики
Без рубрики

Использование шпионов для тестирования в JavaScript с Sinon.js

Sinon.js – это популярные рамки, используемые в автономном тестировании шпионов, заглушки и издевательства для JavaScript. В этой статье мы будем шипиться на HTTP-запрос в модульном тесте.

Автор оригинала: Allan Mogusu.

Вступление

В тестировании программного обеспечения «SPY» записывает, как используется функция, когда оно тестируется. Это включает в себя, сколько раз его назвали, назвали ли он с правильными аргументами, и что было возвращено.

В то время как тесты в основном используются для проверки вывода функции, иногда нам нужно проверить, как функция взаимодействует с другими частями кода.

В этой статье у нас будет глубже посмотреть, какие шпионы и когда их следует использовать. Затем мы шпионизируемся на HTTP-запросе при использовании Sinon.js в тесте с блоком JavaScript.

Эта статья является второй из серии о методах тестирования с Sinon.js. Мы рекомендуем вам прочитать нашу предыдущую статью:

  • Использование заглушек для тестирования в JavaScript с Sinon.js
  • Использование шпионов для тестирования в JavaScript с Sinon.js ( Вы здесь )
  • Использование издеваний для тестирования в JavaScript с Sinon.js

Что такое шпионы?

SPY – это объект в тестировании, которые отслеживает вызовы, сделанные для метода. Отслеживая его вызовы, мы можем проверить, что он используется так, как ожидается, наша функция будет использовать ее.

Верно своему названию, шпион дает нам подробную информацию о том, как используется функция. Сколько раз это было вызвано? Какие аргументы были переданы в функцию?

Давайте рассмотрим функцию, которая проверяет, существует ли пользователь, и создает один в нашей базе данных, если это не так. Мы можем заглушать ответы базы данных и получить правильные пользовательские данные в нашем тесте. Но как мы знаем, что функция на самом деле создает пользователя в случаях, у нас не существующих пользовательских данных? С помощью SPY мы будем наблюдать, сколько раз вызывается функция создания пользователей и будет определена.

Теперь, когда мы знаем, что такое SPY, давайте подумаем о ситуациях, где мы должны использовать их.

Зачем использовать шпики?

Шпионы Excel в том, чтобы дать представление о поведении функции, которую мы тестируем. При подтверждении входов и выходов теста имеет решающее значение, исследуя, как ведет себя функцию, может быть важной во многих сценариях:

Когда ваша функция имеет побочные эффекты, которые не отражены в его результатах, вы должны шпионить на методах, которые он использует.

Примером будет функция, которая возвращает JSON пользователю после выполнения многих вызовов на различные внешние API. Финальная полезная нагрузка JSON не говорит пользователя, как функция извлекает все свои данные. Шпион, который контролирует сколько раз назвал внешние API и какие входы он использовал в этих звонках, расскажет нам, как.

Давайте посмотрим, как мы можем использовать Sinon.js для создания шпионов в нашем коде.

Использование Sinon.js, чтобы создать шпион

Есть несколько способов создавать шпион с Sinon.js, каждый из своих преимуществ и недостатков. Этот учебник будет сосредоточен на следующих двух методах, которые целевые шпионы на одном функции одновременно:

  1. Анонимная функция, которая отслеживает аргументы, значения и вызовы, сделанные для метода.
  2. Обертка к существующей функции.

Во-первых, давайте настроим наш проект, чтобы мы могли запустить наши тестовые файлы и использовать Sinon.js.

Настраивать

Давайте начнем с создания папки для хранения нашего кода JavaScript. Создайте новую папку и перейдите в нее:

$ mkdir SpyTests
$ cd SpyTests

Инициализировать NPM, чтобы вы могли отслеживать установку пакетов:

$ npm init -y

Теперь давайте установим наши зависимости тестирования. Мы устанавливаем Моча и Чай Чтобы запустить наши тесты, наряду с Sinon.js:

$ npm i mocha chai sinon --save-dev

Наша настройка завершена! Давайте начнем с помощью шпионов в качестве анонимных функций.

Шпионы с анонимными функциями

В качестве анонимных функций Sinon.js Spies часто полезны в тех случаях, когда мы хотим тестировать функции более высокого порядка, которые принимают другие функции, то есть обратные вызовы в качестве аргументов. Давайте посмотрим на основной пример, который повторно реализует Array.prototype.map () с обратным вызовом:

Создать два файла i.e mapoPerations.js и mapoPerations.test.js внутри Sputests каталог следующим образом:

$ touch mapOperations.js mapOperations.test.js

Введите следующий код в mapoPerations.js файл:

const map = (array, operation) => {
    let arrayOfMappedItems = [];
    for (let item of array) {
        arrayOfMappedItems.push(operation(item));
    }
    return arrayOfMappedItems;
};

console.log(map([{ name: 'john', role: 'author'}, { name: 'jane', role: 'owner'}], user => user.name));

module.exports = { map };

В коде выше, карта () принимает массив в качестве первого аргумента и функции обратного вызова, Операция () , это преобразует элементы массива в качестве второго аргумента.

Внутри карта () Функция, мы повторяемся через массив и применяем операцию в каждом элементе массива, затем нажимайте результат к arrayofmappyTems множество.

Когда вы запускаете этот пример на консоли, вы должны получить следующий результат:

$ node mapOperations.js
[ 'john', 'jane' ]

Чтобы проверить, будь то Операция () Функция была вызвана нашими карта () Функция, мы можем создать и пройти анонимный шпион для карта () Функция следующим образом:

const { map } = require('./mapOperations');
const sinon = require('sinon');
const expect = require('chai').expect;

describe('test map', () => {
    const operation = sinon.spy();

    it('calls operation', () => {
        map([{ name: 'foo', role: 'author'}, { name: 'bar', role: 'owner'}], operation);
        expect(operation.called);
    });
});

Пока наш обратный вызов на самом деле не преобразует массив, наш шпион может убедиться, что функция, которую мы тестируем на самом деле использует ее. Это подтверждено, когда ожидать (операция. called); не проходит тест.

Посмотрим, пройдет ли наш тест! Запустите тест, вы должны получить следующий вывод:

$ mocha mapOperations.test.js

  test map

    ✓ calls operation


  1 passing (4ms)

✨  Done in 0.58s.

Оно работает! Теперь мы уверены, что наша функция будет использовать любой обратный вызов, который мы ставим в его аргументы. Давайте теперь посмотрим, как мы можем обернуть функцию или метод, используя шпион.

Шпионы как функция или метод обертки

В предыдущей статье мы увидели, как мы можем заглушить HTTP-запрос в наших модульных тестах. Мы будем использовать тот же код, чтобы показать, как мы можем использовать Sinon.js, чтобы шпионить на запросе HTTP.

В новом файле под названием 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 () Метод называет JSON API, который выбирает список фотографий из альбома, идентификатор которого мы проходим как параметр. Ранее мы ограблены request.get () Метод для возврата фиксированного списка фотографий.

На этот раз мы будем шпионить на request.get () Метод, поэтому мы можем проверить, что наша функция делает HTTP-запрос на API. Также мы также проверим, что он сделал запрос один раз, что хорошо, так как мы не хочем ошибки, которая спамала конечную точку API.

В новом тестовом файле под названием index.test.js Напишите следующую линию кода JavaScript по строке:

const expect = require('chai').expect;
const request = require('request');
const sinon = require('sinon');
const index = require('./index');

describe('test getPhotosByAlbumId', () => {
    let requestSpy;
    before(() => {
        requestSpy = sinon.spy(request, 'get');
    });

    after(() => {
        request.get.restore();
    });

    it('should getPhotosByAlbumId', (done) => {
        index.getAlbumById(2).then((photos) => {
            expect(requestSpy.calledOnce);
            expect(requestSpy.args[0][0]).to.equal("https://jsonplaceholder.typicode.com/albums/2/photos?_limit=3");
            photos.forEach(photo => {
                expect(photo).to.have.property('id');
                expect(photo).to.have.property('title');
                expect(photo).to.have.property('url');
            });
            done();
        });
    });
});

В приведенном выше тесте мы завернули request.get () Способ с шпионом во время установки в до () функция. Мы восстанавливаем функцию, когда мы разрываем тест в после () функция.

В тестовом случае мы сделали утверждение о том, что requestspy объект, который трекирует request.get () Использование, только записывает один звонок. Затем мы идем глубже, чтобы подтвердить, что свой первый аргумент request.get () Вызов – это URL URL JSON API. Затем мы сделали утверждения, чтобы позвонить, чтобы фотографии были возвращены ожидаемые свойства.

При запуске теста вы должны получить следующий вывод:

$ mocha index.test.js


  test getPhotosByAlbumId
    ✓ should getPhotosByAlbumId (570ms)


  1 passing (587ms)

✨  Done in 2.53s.

Обратите внимание, что этот тест сделал реальный запрос сети на API. Шпионские обертывания вокруг Функция, это делает не Замените его функциональность!

Кроме того, Sinon.js тестовые заглушки уже шпионы! Если вы когда-нибудь создаете тестовую заглушку, вы сможете увидеть, сколько времени его было вызвано, и аргументы, которые были переданы функции.

Заключение

Шпион в тестировании дает нам способ отслеживания звонков, сделанных в методе, чтобы мы могли проверить, что он работает как ожидалось. Мы используем шпионы, чтобы проверить, назвал ли метод или не вызываемый, сколько раз его назвали, с какими аргументами его называли, а также значение, которое он возвращается при вызове.

В этой статье мы представили концепцию шпионов и увидели, как мы можем использовать Sinon.js для создания шпионов. Мы также смотрели на то, как мы можем создавать шпики как анонимные функции, и как мы можем использовать их для обертывания методов. Для более продвинутых случаев использования Sinon.js предоставляет богатый шпионский API, который мы можем использовать. Для получения более подробной информации о документации можно получить доступ здесь Отказ