15

如何测试 Sinon.js 的函数调用序列?

例如,我在对象中有三 (3) 个处理程序,并且想要定义处理程序调用的序列。这有什么可能吗?

4

4 回答 4

25

http://sinonjs.org/docs/

sinon.assert.callOrder(spy1, spy2, ...)

如果提供的间谍以指定的顺序调用,则通过。

于 2013-03-31T18:29:11.847 回答
3

对于遇到这种情况的人,他们正在寻找一种在调用序列上定义具有指定行为的存根的方法。没有直接的方法(据我所见)说:“这个存根将被调用X多次,在第一次调用时它将接受参数ab在第二次调用时返回它将接受参数 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, ... ]

这样,我们可以在序列中的每个调用上返回特定值,然后断言调用是使用我们预期的参数进行的。

于 2021-01-28T07:00:55.443 回答
0

正如 Gajus 所提到的,它callOrder()不再可用,您可以使用callBefore()calledAfter()和。calledImmediatelyBefore()calledImmediatelyAfter()

spy.getCalls()我发现通过使用和 do assert.deepEqual()for 调用参数获取所有调用来断言一个间谍的顺序调用是最方便的 。

示例 - 断言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)
于 2020-01-19T08:15:59.313 回答
0

还有一个 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);
于 2020-10-11T13:48:26.643 回答