Sinon: Цепочка sinon.stub() с несколькими .withArgs заглушает только последнее объявление

Созданный на 25 сент. 2012  ·  23Комментарии  ·  Источник: sinonjs/sinon

Цепочка sinon.stub() с несколькими .withArgs заглушает только последнее объявление

var stubbedFunction = sinon.stub().withArgs(argument1).returns(value1).withArgs(argument2).returns(value2);

тогда только последнее объявление (.withArgs(argument2).returns(value2)) фактически заглушается

Самый полезный комментарий

Это правильно работает с 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

Все 23 Комментарий

Необходимо изменить 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.

  • Узел 6.9.4
  • НПМ 3.10.10

Извините за поздний ответ

@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) в первой позиции.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги