-
Notifications
You must be signed in to change notification settings - Fork 48
Description
I'm having the following situation:
function reloadApp() {
$.ajax({url: "first/url"}).then(() => {
$.ajax({url: "second/url"}).then(() => updateSomeDOMAttributes());
}).then((r1) => addSomeDOMAttributes());
renderDOMComponent();
}
There are two ajax requests nested but not chained to one another.
I'm using Sinon.js (which uses nise).
I have no way of waiting for the second request to fulfil unless I chain the Promise which is something I cannot do without breaking compatibility (let's assume that it cannot be done).
beforeEach(() => {
server = sinon.createFakeServer({respondImmediately: true});
spy = sinon.spy(tracking, "trackEvent");
});
afterEach(() => {
server.restore();
spy.restore();
});
it('ajax mocking works #1', (done) => {
server.respondWith("GET", 'first/url', [ 200, { "Content-Type": "text/html" }, `mocked1` ]);
server.respondWith("GET", 'second/url', [ 200, { "Content-Type": "text/html" }, `mocked2` ]);
reloadApp().then((r1) => {
expect(r1).to.equal(`mocked1`);
expect(spy.callCount).to.equal(2); <------- fails
done();
});
// server.respond();
});
I tried both strategies with respondImmediately
and with the server.respond()
.
My solution is to make a helper:
/**
* Wait for the Sinon.js nise XHR mocks to finish their registered
* responses.
*
* @param server Server created with sinon.createFakeServer
* @param timeout Optional, how much to wait before failing.
* @returns {Promise<any>}
*/
function waitForServerToFulfillRequests(server, timeout) {
timeout = timeout || 100;
return new Promise((resolve, reject) => {
let checkCount = 0;
const i = setInterval(() => {
if (server.requests.length === server.responses.length) {
clearInterval(i);
resolve();
}
if (checkCount === 100) {
clearInterval(i);
reject(`Maximum waiting count of ${checkCount * 16} has passed.`);
}
checkCount++;
}, 16);
});
}
This is obviously an edge case but my goal is to test the final outcome of the code and wait for all the requests to finish because they modify the HTML component that I'm testing.
Working example: https://github.com/serbanghita/karma-mocha-chai-sinon ;
- https://github.com/serbanghita/karma-mocha-chai-sinon/blob/master/src/MyApp.js (code)
- https://github.com/serbanghita/karma-mocha-chai-sinon/blob/master/test/jQueryAjaxTest.js (test)
Let me know your thoughts on the situation and waitForServerToFulfillRequests