sinon stub withArgs可以匹配一些但不是所有参数

问题描述 投票:50回答:4

我有一个函数我正在使用多个参数调用它。我想检查第一个参数。剩下的就是回调功能,所以我想让他们独自一人。因此,我可能会使用ajax作为示例进行以下2次调用:

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()匹配所有参数,这不会(并且永远不可能,与回调类似)。

我怎样才能让sinon存根根据第一个arg进行检查和设置响应?

sinon
4个回答
94
投票

https://sinonjs.org/releases/latest/matchers/#sinonmatchany

你可以使用sinon.match.any:

method.get.withArgs(25, sinon.match.any, sinon.match.any); 

1
投票

如果您只想检查可以使用的第一个参数

method.get.withArgs(25).calledOnce

要么

method.get.calledWith(25)

1
投票

如果你想在多个参数中只检查一个参数,这个方法对间谍非常有效

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

但是我不明白为什么你在这里使用存根。如果你只想检查函数的调用方式,你应该使用间谍。如果你想检查它的调用方式并改变它的行为(例如:阻止ajax调用),那么你应该使用模拟。

Sinon嘲笑有自己的检查方式。我知道你的情况的唯一方法是使用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


1
投票

withArgs可用于匹配一些但不是所有的参数。

具体来说,method.get.withArgs(25)将只检查第一个参数。


更正

这是不正确的:

withArgs()匹配所有参数


细节

withArgs被召唤时,它会记住它被传递给here作为matchingArguments的论据。

然后当stub被调用时,它获得所有匹配的假货here

在没有第二个参数的情况下调用matchingFakes,因此它返回所有具有matchingArguments that match the arguments passed to the stub starting at index 0 up to the length of matchingArguments的假货。这意味着即使存在其他参数,当matchingArguments与传递的参数的开头匹配时,伪匹配也会匹配。

任何匹配的假货都是sorted by matchingArguments.length,匹配最多参数的那个是invoked


以下测试证实了这种行为并通过了sinon版本1.1.0从7年前开始,版本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

});
© www.soinside.com 2019 - 2024. All rights reserved.