使用 proxyquire 和 sinon.js

问题描述

我正在尝试使用 sinon.js 和 getJSON 存根 jquery 的 donefailproxyquire 函数,但我总是收到一个错误,即 .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 |                   
----------|---------|----------|---------|---------|-------------------

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...