как заглушить request.get три раза?с 2 одинаковыми и 1 разными URL? - PullRequest
0 голосов
/ 31 января 2019

Мне нужно написать тестовый блок для следующего куска кода.Здесь URL-адреса являются внешними вызовами API, поэтому мне нужно их издеваться.Для остальных тестовых случаев я использовал sinon.Поэтому я хотел бы написать их только в sinon .

function 1 {
  async.waterfall() {
    function 2();
    function 3();
  }
}

function 2(callback) {
    url2_1 = "/calculatorFunctionList"
    request.get(url2_1,function (err, res, body) {
        return callback("with some diff response")
    })}

function 3(callback) {
    url3_1 = "addition/values="+somevalue1
    url3_2 = "addition/values="+somevalue2
    request.get(url3_1,function (err, res, body) {
        if(!err) {
            request.get(url3_2, function (err, res, body) {
                return callback("with some response")
            })
        }
    })
}

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

1 Ответ

0 голосов
/ 08 февраля 2019

Sinon - по своей сути (на минутку забудь lolex и nise) - явно имеет дело с заглушкой и слежкой за функциями javascript.Вот и все.Он не имеет отношения к загрузчикам модулей или Node как таковым .

Так что он не знает, как подключиться к загрузчику модулей Node (require) и отключить зависимости самостоятельно.В общем случае у вас есть два варианта:

  1. Обеспечьте свой модуль (тестируемая система) точками впрыска (скажем, function setRequestModule(module){ request = module }, которые можно использовать для питания заглушки Sinon.
  2. Использование уровня связи для перехвата вызовов системы модулей для загрузки зависимостей и их замены. См. эту статью в разделе с инструкциями Sinon , чтобы узнать, как это сделать.

Это был общий случай, но так как вы имеете дело с заглушкой сетевого уровня, существует третий вариант, связанный со вторым, который включает в себя подключение к слою http в Node и настройку fakeзапросы и ответы там с использованием nock.

Это будет выглядеть так:

const nock = require('nock')

const scope = nock('https://api.github.com')
  .get('/repos/atom/atom/license')
  .reply(200, {
    license: {
      key: 'mit',
      name: 'MIT License',
      spdx_id: 'MIT',
      url: 'https://api.github.com/licenses/mit',
      node_id: 'MDc6TGljZW5zZTEz',
    },
  })

Это то, что я обычно делаю, но, поскольку вы настаиваете на использовании только Sinon, вы остаетесь спервый вариант.

Разработка первого варианта: ввести зависимости

Ваши функции 2 и 3 (недопустимые идентификаторы JavaScript, кстати) зависят отмодуль request и его метод get для получения результатов.Чтобы иметь возможность контролировать то, что возвращает request.get, вам нужно будет предоставить вашему модулю другую версию request для ваших тестов.Это можно сделать с помощью внедрения зависимостей.

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

const request = require('request');

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

let request = require('request');

Чтобы иметь возможность контролировать свою зависимость, теперь вы можете добавитьновая функция для ваших экспортов:

module.exports.setRequestModule = function (stub){
    request = stub;
}

Чтобы использовать это в своих тестах, вам нужно будет сделать это в своих тестах:

const myModule = require('../src/my-module');
const myRequestStub = {};

myModule.setRequestModule(myRequestStub);

it('should return the expected response', () => {
    const expectedOutput = "with some response";
    myRequestStub.get = function (url, callback) {
         callback(null, expectedOutput);
    }

    myModule.doSomething() ...
    // do test
});

В качестве альтернативы Вы может также выставить объект запроса в вашем модуле:

module.exports._request = request;

Затем вы можете, например, использовать sinon, чтобы инструментировать его, заглушив метод get из ваших тестов.

const myModule = require('../src/my-module');

sinon.stub(myModule._request, 'get').callsFake( (url, cb) => cb("hello!") );
...