web-dev-qa-db-ja.com

すべての引数ではなく一部の引数に一致するsinonスタブ

複数の引数で呼び出されるスタブ化する関数があります。 最初の引数だけを確認したい。残りはコールバック関数なので、そのままにしておきます。したがって、例として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)と2番目のget(10)を区別しないためです。しかし、method.get.withArgs(25).calls...を使用すると、withArgs()all引数と一致するため、どちらとも一致しません。 )。

最初の引数のみに基づいて応答をチェックおよび設定するために、どうすればsinonスタブを取得できますか?

53
deitch

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

Sinon.match.anyを使用できます。

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

最初の引数を確認したいだけなら、使用できます

method.get.withArgs(25).calledOnce

または

method.get.calledWith(25)
1
igor

解決

withArgscanは、すべてではなく一部の引数と一致するために使用されます。

具体的には、method.get.withArgs(25)will check最初の引数のみ


補正

これは間違っています:

withArgs()は、all引数と一致します


詳細

withArgsが呼び出されると、渡された引数を記憶します here as matchingArguments

次に、stubが呼び出されると、一致するすべての偽物 here を取得します。

matchingFakes は2番目のパラメーターなしで呼び出されるため、matchingArgumentsを持つすべての偽物を返します stubに渡される引数に一致インデックス0でmatchingArguments の長さまで。これは、そのmatchingArgumentsが渡された引数の先頭と一致するときに偽物が一致することを意味します追加の引数がある場合でも

一致する偽物は matchingArguments.lengthでソート になり、ほとんどの引数に一致するものは invoked になります。


次のテストでは、この動作を確認し、7年前のsinonバージョン1.1.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

});

このメソッドは、多数の引数のうち1つだけをチェックする場合にスパイで非常にうまく機能します。

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

1