【发布时间】:2013-03-21 18:51:31
【问题描述】:
如何测试 Sinon.js 的函数调用顺序?
例如,我在对象中有三 (3) 个处理程序,并且想要定义处理程序调用的序列。这有什么可能吗?
【问题讨论】:
标签: javascript unit-testing sinon
如何测试 Sinon.js 的函数调用顺序?
例如,我在对象中有三 (3) 个处理程序,并且想要定义处理程序调用的序列。这有什么可能吗?
【问题讨论】:
标签: javascript unit-testing sinon
【讨论】:
sinon.assert.callOrder.apply(sinon.assert, [spy1, spy2, spy3]);
callOrder 似乎已被删除。目前的做法是使用calledBefore及相关方法。
对于遇到这种情况的人,他们正在寻找一种方法来定义在调用序列上具有指定行为的存根。没有直接的方法(据我所见)说:“这个存根将被称为X 次,在第一次调用时它将采用参数a 并在第二次调用时返回b取参数c 并返回d ...”等等。
我发现最接近这种行为的是:
const expectation = sinon.stub()
.exactly(N)
.onCall(0)
.returns(b)
.onCall(1)
.returns(d)
// ...
;
// Test that will end up calling the stub
// expectation.callCount should be N
// expectation.getCalls().map(call => call.args) should be [ a, b, ... ]
这样我们可以在序列中的每个调用上返回特定值,然后断言调用是使用我们预期的参数进行的。
【讨论】:
正如 Gajus 所说,callOrder() 不再可用,您可以使用 callBefore()、calledAfter()、calledImmediatelyBefore() 和 calledImmediatelyAfter()。
我发现通过使用spy.getCalls() 获取所有调用并对调用参数执行assert.deepEqual() 来断言对一个间谍的连续调用最方便。
示例 - 断言console.log() 调用的顺序。
// func to test
function testee() {
console.log(`a`)
console.log(`b`)
console.log(`c`)
}
在你的测试用例中
const expected = [`a`, `b`, `c`]
const consoleSpy = spy(console, 'log')
testee()
const result = consoleSpy.getCalls().map(({ args }) => args[0])
assert.deepEqual(result, expected)
【讨论】:
还有一个 sinon-chai 插件。
https://www.npmjs.com/package/sinon-chai-in-order
expect(spy).inOrder.to.have.been.calledWith(1)
.subsequently.calledWith(2)
.subsequently.calledWith(3);
【讨论】: