Почему я не могу правильно заглушить библиотеку twilio с помощью sinon? - PullRequest
0 голосов
/ 08 октября 2018

В моем коде у меня есть:

function handleMessage() {
  const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
  let recordings = twilio.recordings(foundConference.RecordingSid);
  console.log('recordings', recordings);
  return recordings.remove();
}

И в моей заглушке у меня есть:

const sinon = require('sinon');
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);

exports.twilioRecordings = () => {
  console.log('about to stub', twilio.recordings);
  sinon.stub(twilio, 'recordings').returns('here');
  console.log('finished stub', twilio.recordings);

  return;
};

Однако на самом деле это не создает функцию-заглушку.Он все еще использует оригинальную функцию recordings.Что я делаю не так?

1 Ответ

0 голосов
/ 17 октября 2018

Пакет Twilio npm возвращает функцию, которая создает новый объект при каждом вызове , это , а не singleton .Таким образом, ваш закороченный экземпляр twilio предназначен только для теста.

Также twilio.recordings (как и все другие свойства) определяется через функцию-получатель в прототипе , поэтому они только для чтения :

Object.defineProperty(Twilio.prototype,
  'recordings', {
  get: function() {
    return this.api.account.recordings;
  }
});

Таким образом, фактический экземпляр twilio не работает.За исключением случаев, когда вы меняете прототип экземпляра , но я не думаю, что это стоит делать просто для модульного тестирования.

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

function getTwilio() {
   return require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
}

Далее ваш hangleMessage будет выглядеть следующим образом:

function handleMessage() {
  const twilio = this.getTwilio();
  const recordings = twilio.recordings(...);
  ...
}

И затем, в вашем тесте вы можете заглушить getTwilio(), чтобы вернуть заглушку:

const twilioStub = {
    recordings: sinon.stub(),
    remove: sinon.stub()
}
sinon.stub(myAwesomeModule, 'getTwilio').returns(twilioStub);

Вы также можете рассмотреть возможность использования пакета mock-require :

const sinon = require('sinon');
const mock = require('mock-require');
mock('twilio', () => ({
  recordings: sinon.stub(),
}));

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

Надеюсь, это поможет.

...