问题描述
我正在尝试使用 sinon.js 和 getJSON
存根 jquery 的 done
、fail
和 proxyquire
函数,但我总是收到一个错误,即 .getJSON,done并且失败不是功能。
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;
测试
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();
});
});
我的要求是测试这两个功能,但我无法做到这一点。我已经花了两天时间,但无法存根 getJSON、done 和 fail 函数。
非常感谢任何帮助
解决方法
使用 sinon.stub()
存根 $.getJSON()
方法及其返回值 JQuery.jqXHR
,它具有 .done()
和 .fail()
回调。您可以使用 .callsFake()
方法获取传入的原始回调,获取它们后,使用模拟数据或错误手动调用这些回调。
您不需要使用 proxyquire
包。
例如
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);
}),'getJSON').returns(mJqXHR);
showProgressBars();
sinon.assert.calledOnce(getJSONStub);
sinon.assert.calledWithExactly(mJqXHR.fail,sinon.match.func);
});
});
单元测试结果:
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 |
----------|---------|----------|---------|---------|-------------------