使用sinon间谍验证函数调用和检查参数

fil*_*lur 22 javascript unit-testing sinon

我想验证从我的单元测试中bar()调用内部foo().

我认为Sinon间谍可能是合适的,但我不知道如何使用它们.

有没有办法检查方法是否被调用?甚至可能提取调用中使用的参数bar()

var spy = sinon.spy(foo);

function foo(){
    bar(1,2,3);
}

function bar(){ }

foo();

// what to do with the spy?
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/8by9jg07/

pht*_*ier 30

在你的情况下,你试图看看是否bar被调用,所以你想要间谍bar而不是foo.

文档中所述:

function bar(x,y) {
  console.debug(x, y);
}
function foo(z) {
  bar(z, z+1);
}
// Spy on the function "bar" of the global object.
var spy = sinon.spy(window, "bar");

// Now, the "bar" function has been replaced by a "Spy" object
// (so this is not necessarily what you want to do) 

foo(1);

bar.getCall(0).args => should be [1,2]
Run Code Online (Sandbox Code Playgroud)

现在,监视函数内部强烈地将你对"foo"的测试与它的实现结合起来,所以你将陷入通常的"模仿者与经典"辩论之中.

  • 根据[doc](http://sinonjs.org/docs),它应该是`getCall(0)`而不是`getCalls(0)` (8认同)
  • 最后,您可以像这样轻松断言调用参数:“expect(window.bar.getCall(0).args).deep.equal([1, 2]);” (2认同)

小智 9

我同意阿德里安的说法,你可能想偷窥吧.

var barSpy = sinon.spy(bar);
Run Code Online (Sandbox Code Playgroud)

然后检查它是否被调用过一次

assert(barSpy.calledOnce);
Run Code Online (Sandbox Code Playgroud)

刚刚打过电话

assert(barSpy.called)
Run Code Online (Sandbox Code Playgroud)

被称为x次

assert.equal(barSpy.callCount, x);
Run Code Online (Sandbox Code Playgroud)

如果你想从第一次调用spy中提取参数:

var args = barSpy.getCalls()[0].args
Run Code Online (Sandbox Code Playgroud)

然后你可以用这些参数做你想做的事.

  • @try-catch-finally 您可以发布技术上正确的答案吗? (3认同)
  • 这个答案在技术上是错误的。你不能[以这种方式使用`spy()`](https://github.com/sinonjs/sinon/blob/v2.3.6/lib/sinon/spy.js#L19) - 它需要一个对象和一个方法名称作为参数 1 和 2(这也是 2015 年旧版本的情况)。如果只用一个函数调用它[创建一个以传递的函数命名的匿名间谍函数](https://github.com/sinonjs/sinon/blob/v2.3.6/lib/sinon/spy.js#L135)并返回它,传递的引用不会改变。 (2认同)