Цепочка sinon.stub() с несколькими .withArgs заглушает только последнее объявление
var stubbedFunction = sinon.stub().withArgs(argument1).returns(value1).withArgs(argument2).returns(value2);
тогда только последнее объявление (.withArgs(argument2).returns(value2)) фактически заглушается
Необходимо изменить withArgs
и вернуть исходную заглушку, из которой она была создана, если она доступна.
+1 За это. В связи с этим я хотел бы, чтобы withArgs
дополнительно разрешал переход к исходному методу для несовпадающих аргументов.
Например, если я хочу заглушить метод Node.js fs.readFileSync()
, я хочу, чтобы Sinon сохранил исходную реализацию, чтобы require()
(который использует readFileSync
) не был нарушен, но используйте заглушенный метод для определенного файла для моих тестов.
Пример предыдущего комментария:
beforeEach(function() {
global.fs = require('fs');
sinon.stub(fs, 'readFileSync').onlyWithArgs('my-file.txt').returns('Contents of file');
// Then require the module under test, which uses fs.readFileSync() internally
// require() uses original method with correct calling context
global.myModule = require('../src/my-module');
});
afterEach(function() {
fs.readFileSync.restore();
});
it('does something with the file', function() {
expect(myModule.loadFromFile()).toEqual('Contents of file');
});
Я хотел бы предложить, чтобы сообщение @froots выше было размещено где-нибудь в документах. Я долго искал, прежде чем нашел это решение о том, как издеваться над файлами, которые включают другие зависимости, через require
Хорошая идея. Хотите попробовать? http://github.com/cjohansen/sinon-web/
Это правильно работает с Sinon 1.7.3:
var s = sinon.stub();
s.withArgs(1).returns('a');
s.withArgs(2).returns('b');
s(1); // -> 'a'
s(2); // -> 'b'
s(3) // -> undefined
Я не думаю, что это пример того, как он работает, так как он все еще не связан (вы должны использовать оригинальную заглушку/макет).
Истинный. Но это достаточно хорошо, и это дает понять, что происходит. Цепочка оставляет место для интерпретации.
Я согласен с @mantoni. Целью заглушки является указание контрактного ответа службы/запроса. Этот стиль выражает это лучше.
Я думаю, что документы, вероятно, могут быть улучшены здесь.
Я ожидал, что сработает следующее:
var someObj = {
someProp: sinon.stub().withArgs("foo").returns(true)
}
Это явно не сработало, как задумано. Но, что более важно, это не потерпело неудачу правильно. Вместо того, чтобы someObj.someProp
не возвращал true, когда foo
не был предоставлен, он всегда возвращал true
. Поскольку предложение returns
возвращает экземпляр Behavior, someObj.someProp
покорно возвращает true
независимо от ввода.
Я понимаю смысл структуры цепочки, возвращающей разные типы объектов. Но пользователи введены в заблуждение относительно того, что это за возвращенные объекты. Поскольку методы, предоставляемые CallObjects и Behaviors, соответствуют API, предоставляемому заглушками, легко понять, почему можно предположить, что они _были_ заглушками.
Я согласен с @jasonkarns. Я только что попал в ту же «ловушку»: встраивание объявления заглушки не возвращает ожидаемый экземпляр заглушки. Однако цепочка работает, как и ожидалось, при использовании макетов:
var someObj = {
someProp: sinon.mock().withArgs("foo").returns(true)
}
Есть ли для этого причина?
Не уверен, что я что-то упускаю, но возможна ли сейчас точка @froots ? Пришлось сделать так:
sinon.stub(fs, 'readdirSync', (dir) => {
if (dir === 'foo-path') {
return [
'my.js',
'fake.js',
'stuff.js'
];
}
return fsReaddir(dir);
});
Хотел сделать что-то вроде:
var myStub = sinon.stub(fs, 'readdirSync', fs.readdirSync);
myStub
.withArgs('foo-path')
.returns([
'my.js',
'fake.js',
'stuff.js'
]);
Я думаю, что это исправлено, приведенный ниже пример работает, как и предполагалось, с [email protected]
var Dummy = {
doSomething: function(something) {
return 'doing ...' + something;
}
}
sinon.stub(Dummy, 'doSomething')
.withArgs('sleep').returns('sleepy')
.withArgs('eat').returns('eating');
console.log(Dummy.doSomething('sleep'));
console.log(Dummy.doSomething('eat'));
@ valentin-radulescu-hs на моей стороне все еще не работает 1.17.7
.
Он по-прежнему принимает последний returns
в качестве единственного возвращаемого значения, независимо от withArgs
(как указано @jasonkarns https://github.com/sinonjs/sinon/issues/176#issuecomment- 78191790).
Что работает для меня, так это ответ @mantoni https://github.com/sinonjs/sinon/issues/176#issuecomment -33636496, не связывая withArgs()
в цепочку.
var s = sinon.stub();
s.withArgs(1).returns('a');
s.withArgs(2).returns('b');
@zurfyx вы работаете на узле или в браузере? Какую версию узла/браузера вы используете? Не уверен, что это имеет значение, но я хотел бы попробовать повторить на своем конце.
Привет, @valentin-radulescu-hs. Я запускаю его на узле, используя babel-cli
6.22.2.
Извините за поздний ответ
@zurfyx Я попытался воспроизвести упомянутую вами конфигурацию, используя тот же код, который я написал выше , и он выводит на консоль sleepy
и eating
, как и ожидалось. Не знаю, почему это вызывает у вас проблемы 😢
@zurfyx Чтобы быть _полностью_ уверенным, вы пробовали это?
grep version node_modules/sinon/package.json
rm -r node_modules
rm npm-shrinkwrap
npm install
grep version node_modules/sinon/package.json
В большинстве случаев у меня возникают проблемы из-за того, что версия пакета, которую я ожидаю, не совпадает с установленной.
@ fatso83 тоже не работает. Выходная версия grep
по-прежнему 1.1.7.7
.
Это мой полный тест, если он может помочь:
it('test', () => {
const s = sinon.stub();
s.withArgs('a').returns('1');
s.withArgs('b').returns('2');
console.info(s('c'));
});
s('a')
: '1'
✓
s('b')
: '2'
✓
s('c')
: undefined
✓
it('test', () => {
const s = sinon.stub()
.withArgs('a').returns('1')
.withArgs('b').returns('2');
console.info(s('c'));
});
s('a')
: '2'
✗
s('b')
: '2'
✓
s('c')
: '2'
✗
Я также могу воспроизвести это поведение, используя sinon.createStubInstance.
const stub = sandbox.stub();
const myObj = function(){};
const objOne = sinon.createStubInstance(myObj);
const objTwo = sinon.createStubInstance(myObj);
stub.withArgs(objOne).returns('1');
stub.withArgs(objTwo).returns('2');
console.info(stub(objOne));
console.info(stub(objTwo));
Выход:
2
2
Я думал, что sinon.createStubInstance должен создавать новый объект-заглушку. Это неправильно?
Я не совсем уверен, относится ли этот вопрос к этой теме, но он определенно имеет к этому какое-то отношение. В проекте с sinon 1.17.7
я использовал цепочку из нескольких операторов withArgs
, где последним был сопоставитель «захватить все», который действовал по умолчанию. Например:
const s = sinon.stub();
s.withArgs(1).returns(1)
.withArgs(2).returns(2)
.withArgs(sinon.match.any).returns('my-default-value')
s(1) // 1
s(5) // my-default-value
Теперь я использую 4.1.3
и поведение изменилось, оно всегда возвращает my-default-value
. Это было задумано? Если да, то есть ли способ определить значение по умолчанию/резервное значение в цепочке withArgs
?
Я не думаю, что когда-либо предполагалось изменение. Если вы можете предоставить исправление для
регресс не стесняйтесь! Я могу помочь отследить, где это произошло, используя got
обвинять.
Ден человек. 15. янв. 2018, 13.11.2018 Дэвид Гарсия уведомления[email protected] :
Я не совсем уверен, относится ли этот вопрос к этой теме, но он
определенно имеет к этому какое-то отношение. В проекте с синон 1.17.7 я
используется для объединения нескольких операторов withArgs, где последним был оператор
Сопоставитель «захватить все», который действовал по умолчанию. Например:const s = sinon.stub();s.withArgs(1).returns(1)
.withArgs(2).returns(2)
.withArgs(sinon.match.any).returns('my-default-value')
s(1) // 1s(5) // мое значение по умолчаниюТеперь я использую 4.1.3, и поведение изменилось, оно всегда возвращается
мое значение по умолчанию. Это было задумано? Если да, то есть ли способ определить
значение по умолчанию/резервное значение в цепочке withArgs?—
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/sinonjs/sinon/issues/176#issuecomment-357638653 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAluXMzqALJ0JlAM3hUaiK1SSyca9H74ks5tKyS4gaJpZM4AK2eu
.>
[изображение: --]
Карл-Эрик Копсенг
[изображение: https://]about.me/kopseng
https://about.me/kopseng?promo=email_sig&utm_source=email_sig&utm_medium=email_sig&utm_campaign=external_links
@ fatso83 Я сузил его, и, видимо, это было сделано специально . Мне кажется более естественным указать запасной вариант в последнем выражении withArgs
, хотя в этом случае проблема решается простым изменением порядка и размещением .withArgs(sinon.match.any)
в первой позиции.
Самый полезный комментарий
Это правильно работает с Sinon 1.7.3: