Подтвердить что ты не робот

Может ли sinon stub withArgs сопоставлять некоторые, но не все аргументы

У меня есть функция я stubbing, которая вызывается с несколькими аргументами. Я хочу проверить только первый аргумент. Остальные функции обратного вызова, поэтому я хочу оставить их в покое. Таким образом, у меня могут быть следующие 2 вызова, используя ajax в качестве примера:

method.get = sinon.stub();
method.get(25,function(){/* success callback */},function(){/* error callback */});         
method.get(10,function(){/* success callback */},function(){/* error callback */});

Я не могу использовать method.get.calls..., потому что тогда он не различает первый get(25) и второй get(10). Но если я использую method.get.withArgs(25).calls..., то он не совпадает ни с чем, потому что withArgs() соответствует аргументам all, что это не так (и никогда не было, с такими обратными вызовами).

Как получить столбцы sinon для проверки и установки ответов на основе только 1-го аргумента?

4b9b3361

Ответ 2

Если вы просто хотите проверить первый аргумент, вы можете использовать

method.get.withArgs(25).calledOnce

или

method.get.calledWith(25)

Ответ 3

Решение

withArgs можно использовать для сопоставления некоторым, но не всем аргументам.

В частности, method.get.withArgs(25) проверит только первый аргумент.


коррекция

Это неверно:

withArgs() соответствует всем аргументам


подробности

Когда withArgs он запоминает аргументы, которые он передал здесь как matchingArguments.

Тогда, когда stub называется она получает все соответствующие фальшивки здесь.

matchingFakes вызывается без второго параметра, поэтому он возвращает все подделки, которые имеют matchingArguments которые соответствуют аргументам, переданным в stub начиная с индекса 0 до длины matchingArguments. Это означает, что подделка будет соответствовать, когда ее matchingArguments соответствуют началу переданных аргументов, даже если есть дополнительные аргументы.

Любые совпадающие подделки затем сортируются по matchingArguments.length и тот, который соответствует большинству аргументов, является тем, который вызывается.


Следующий тест подтверждает это поведение и проходит с версией sinon версии 1.1.0 от 7 лет назад, версии 1.14.0 с момента 1.14.0 этого вопроса и текущей версии 6.3.5:

import * as sinon from 'sinon';

test('withArgs', () => {

  const stub = sinon.stub();

  stub.withArgs(25).returns('first arg is 25!');
  stub.returns('default response');

  expect(stub(25)).toBe('first arg is 25!');  // SUCCESS
  expect(stub(25, function () { }, function () { })).toBe('first arg is 25!');  // SUCCESS
  expect(stub(10, function () { }, function () { })).toBe('default response');  // SUCCESS

});

Ответ 4

этот метод очень хорошо работает со шпионами, если вы хотите проверить только один аргумент среди многих

it('should check only first argument', function ():void {
            myFunction('foo', 'bar', baz');
            expect(myFunctionSpy.firstCall.args[0]).to.equal('foo');
        });

Однако я не понимаю, почему вы используете здесь заглушки. Если вы просто хотите проверить, как вызывается функция, вы должны использовать шпиона. Если вы хотите проверить, как он называется И изменить его поведение (например: блокирование вызовов ajax), вы должны использовать макет.

Синоны издеваются по-своему. Единственный способ, который я знаю для вашего дела, - использовать sinon.match.many для аргументов, которые вы не хотите проверять:

it('should check only first argument', async function (): Promise<void> {
                mock.expects('myFunction').withExactArgs('foo', sinon.match.any, sinon.match.any).returns('foo');
                await myFunction('foo', 'bar', baz');
                mock.verify();
            });

mock.verify() перейдет к тестированию И сбросит макет для других тестов, в случае использования шпиона или заглушки вы должны делать это вручную с помощью функции restore() или reset() после каждого теста

PD: извините за синтаксис TypeScript здесь: p