I am trying to stub getJSON
, done
and fail
function of jquery using sinon.js and proxyquire
but always I am getting an error that .getJSON, done and fail is not function.
const $ = require("jquery");
const Progress = (() => {
const getData = () => {
return $.getJSON();
};
const showProgressBars = () => {
getData()
.done(function (data) {
console.log(data);
})
.fail(function (e) {
console.log("error getting data.", e);
});
};
return {
getData,
showProgressBars
}
})();
module.exports=Progress;
Test
const proxyquire=require("proxyquire");
const sinon=require("sinon");
const expect=require("chai").expect;
describe("Progress", () => {
it("should call getJSON", (done) => {
const getJSONStub = sinon.stub();
const jquerySpy = sinon.stub().callsFake(() => {
return {
getJSON: getJSONStub,
};
});
const { getData } = proxyquire("../src/demo", {
jquery: jquerySpy,
});
getData();
expect(getJSONStub.callCount).to.be.eq(1);
done();
});
});
My requirement is to test these two functions but I am unable to do this. I already spent two days but unable to stub the getJSON, done and fail function.
Any help sould be highly appreciated
Use sinon.stub()
to stub $.getJSON()
method and its returned value JQuery.jqXHR
which has .done()
and .fail()
callbacks. You can get the original callback passed in using .callsFake()
method, after getting them, call these callbacks manually with mocked data or error.
You don't need to use proxyquire
package.
E.g.
index.js
:
const $ = require('jquery');
const Progress = (() => {
const getData = () => {
return $.getJSON();
};
const showProgressBars = () => {
getData()
.done(function (data) {
console.log(data);
})
.fail(function (e) {
console.log('error getting data.', e);
});
};
return {
getData,
showProgressBars,
};
})();
module.exports = Progress;
index.test.js
:
const sinon = require('sinon');
const expect = require('chai').expect;
const $ = require('jquery');
const { getData, showProgressBars } = require('./');
describe('Progress', () => {
afterEach(() => {
sinon.restore();
});
it('should call getJSON', async () => {
const data = 'teresa teng';
const getJSONStub = sinon.stub($, 'getJSON').resolves(data);
const res = await getData();
expect(res).to.be.equal('teresa teng');
sinon.assert.calledOnce(getJSONStub);
});
it('should get data success', () => {
const data = 'teresa teng';
const mJqXHR = {
done: sinon.stub().callsFake(function (callback) {
callback(data);
return this;
}),
fail: sinon.stub(),
};
const getJSONStub = sinon.stub($, 'getJSON').returns(mJqXHR);
showProgressBars();
sinon.assert.calledOnce(getJSONStub);
sinon.assert.calledWithExactly(mJqXHR.done, sinon.match.func);
});
it('should handle error if get data fail', () => {
const mErr = new Error('network');
const mJqXHR = {
done: sinon.stub().returnsThis(),
fail: sinon.stub().callsFake(function (callback) {
callback(mErr);
}),
};
const getJSONStub = sinon.stub($, 'getJSON').returns(mJqXHR);
showProgressBars();
sinon.assert.calledOnce(getJSONStub);
sinon.assert.calledWithExactly(mJqXHR.fail, sinon.match.func);
});
});
unit test result:
Progress
✓ should call getJSON
teresa teng
✓ should get data success
error getting data. Error: network
at Context.<anonymous> (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/src/stackoverflow/67267452/index.test.js:34:18)
at callFn (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runnable.js:364:21)
at Test.Runnable.run (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runnable.js:352:5)
at Runner.runTest (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:677:10)
at /Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:801:12
at next (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:594:14)
at /Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:604:7
at next (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:486:14)
at Immediate._onImmediate (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:572:5)
at processImmediate (internal/timers.js:461:21)
✓ should handle error if get data fail
3 passing (12ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------