Функция заглушки Sinon используется с деструктуризацией - PullRequest
0 голосов
/ 01 октября 2018

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

 const { theFunctionIWant } = require('path/to/module')

При тестировании заглушка никогда не вызывается, и реальная функция продолжает вызываться.Но когда мне требуется «нормально» (то есть: без деструктурирования)

const myModule = require('path/to/module')

, тогда заглушка используется правильно и все работает отлично

Я чувствую, что это из-за того, как деструктура работает итот факт, что sinon заглушает свойство объекта, а не функцию напрямую.Во всяком случае, если вы можете предоставить мне некоторые идеи, я буду благодарен!

Ответы [ 2 ]

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

Причина, по которой заглушка метода модуля не работает при использовании деструктурирования из зависимого модуля, довольно проста и связана со временем, когда вы привязываете фактическую ссылку на функцию.Он не имеет ничего общего с модулями CommonJS, Sinon или Node как таковыми, поэтому я начну с простых примеров JavaScript.

const stub = (o, method) => (o[method] = () => "I am a stub");

const obj = {
  methodFoo() {
    return "I am foo";
  }
};

// same as doing `const methodFoo = obj.methodFoo;`
const { methodFoo } = obj; // "import" using destructuring

console.log("obj.methodFoo(): ", obj.methodFoo());
console.log("methodFoo()", methodFoo());

console.log("Stubbing out method!");
stub(obj, "methodFoo");

console.log("obj.methodFoo: ", obj.methodFoo());
console.log("methodFoo()", methodFoo());

Если вы запустите приведенный выше пример, вы увидите, что, даже если вы отметили свойство methodFoo obj «модуля», прямая ссылка по-прежнемувозвращает старое значение!

Это потому, что при создании заглушки вы по существу присваиваете новое значение (функцию) свойству объекта (здесь: obj).Новые ссылки на это новое значение (с использованием obj.methodFoo) будут печатать новые значения, , но если вы сохранили ссылку на старую функцию , вы все равно получите старые возвращаемые значения при вызове старой функции.

То же самое относится и к вашей первоначальной проблеме.Если у вас в модуле A есть зависимость от функции foo в модуле B и хранит эту ссылку, то не имеет значения, назначаете ли вы новое значение (например, заглушку) экспортируемому значению, поскольку вы уже сохранили ссылку на старое значение.

По сути:

На это будет влиять заглушка

const A = require('./A');

function doFoo(){
    A.foo(); // will always evalute  A['foo']()
}

На заглушку это не повлияет

const myFoo = require('./A').foo;

function doFoo(){
    myFoo(); // will just evalute to the original value of A.foo()
}
0 голосов
/ 01 октября 2018

Поскольку ваш модуль возвращает объект, а theMethodIwant является свойством этого объекта, вы можете определить свою заглушку следующим образом:

const myModule = require('path/to/module')
myModule.theMethodIwant = sinon.stub()
...