How can I test sequence of function calls by Sinon.js?
For example i have three (3) handlers in object, and want define sequence of handler calls. Is there any possibilities for this?
How can I test sequence of function calls by Sinon.js?
For example i have three (3) handlers in object, and want define sequence of handler calls. Is there any possibilities for this?
sinon.assert.callOrder(spy1, spy2, ...)
Passes if the provided spies where called in the specified order.
callOrder
has been removed. The current approach is to use calledBefore
and the related methods. –
Skedaddle For people who run into this looking for a way to define stubs with a specified behaviour on a call sequence. There is no direct way (as far as I've seen) to say: "This stub will be called X
times, on the 1st call it will take parameter a
and return b
on the 2nd call it will take parameter c
and return d
..." and so on.
The closest I found to this behaviour is:
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, ... ]
This way we can return specific values on each call in the sequence and then assert that the calls were made with the parameters we expected.
There is also a sinon-chai plugin.
https://www.npmjs.com/package/sinon-chai-in-order
expect(spy).inOrder.to.have.been.calledWith(1)
.subsequently.calledWith(2)
.subsequently.calledWith(3);
As Gajus mentioned callOrder()
is no longer available and you can use callBefore()
, calledAfter()
, calledImmediatelyBefore()
and calledImmediatelyAfter()
.
I found most convenient to assert sequential calls of one spy by getting all calls using spy.getCalls()
and do assert.deepEqual()
for call arguments.
Example - Assert order of console.log()
calls.
// func to test
function testee() {
console.log(`a`)
console.log(`b`)
console.log(`c`)
}
In your test case
const expected = [`a`, `b`, `c`]
const consoleSpy = spy(console, 'log')
testee()
const result = consoleSpy.getCalls().map(({ args }) => args[0])
assert.deepEqual(result, expected)
Use spy.calledBefore(anotherSpy)
to assert one spy is called before the other.
You can see an example of it in the stub documentation:
require("@fatso83/mini-mocha").install();
const sinon = require("sinon");
const PubSub = require("pubsub-js");
const referee = require("@sinonjs/referee");
const assert = referee.assert;
describe("PubSub", function () {
it("should call all subscribers, even if there are exceptions", function () {
const message = "an example message";
const stub = sinon.stub().throws();
const spy1 = sinon.spy();
const spy2 = sinon.spy();
const clock = sinon.useFakeTimers();
PubSub.subscribe(message, stub);
PubSub.subscribe(message, spy1);
PubSub.subscribe(message, spy2);
assert.exception(() => {
PubSub.publishSync(message, "some data");
// PubSubJS reschedules exceptions using setTimeout(fn,0)
// We have faked the clock, so just tick the clock to throw!
clock.tick(1);
});
assert.exception(stub);
assert(spy1.called);
assert(spy2.called);
assert(stub.calledBefore(spy1)); // <----- HERE
clock.restore();
});
});
There are similar tools documented in that first link:
spy.calledBefore(anotherSpy);
Returns true if the spy was called before anotherSpy
spy.calledAfter(anotherSpy);
Returns true if the spy was called after anotherSpy
spy.calledImmediatelyBefore(anotherSpy);
Returns true if spy was called before anotherSpy, and no spy calls occurred between spy and anotherSpy.
spy.calledImmediatelyAfter(anotherSpy);
Returns true if spy was called after anotherSpy, and no spy calls occurred between anotherSpy and spy.
© 2022 - 2024 — McMap. All rights reserved.
sinon.assert.callOrder.apply(sinon.assert, [spy1, spy2, spy3]);
– Recession