0

有时,在一个模块中,函数会调用其他函数(用于因式分解、代码抽象等),我们可能希望在不测试内部函数的情况下测试调用者函数。

但是,此代码不能按原样工作:

// src/my-module.js

function externalFunction() {
  return internalFunction();
}

function internalFunction() {
  return { omg: 'this is real' };
}

module.exports = {
  externalFunction,
};
// test/my-module.spec.js

const { assert } = require('chai');
const {
  describe,
  it,
  before,
  beforeEach,
} = require('mocha');
const sinon = require('sinon');

let myModule;

describe('externalFunction', () => {
  before(() => {
    myModule = require('../src/my-module');
  });

  beforeEach(() => {
    // partial stubbing not working
    sinon.stub(myModule, 'internalFunction').callsFake(() => ({ omg: 'this is fake' }));
  })

  it('returns the result of internalFunction', () => { // FAILING
    const result = myModule.externalFunction();
    assert.deepEqual(result, { omg: 'this is fake' });
  });
});
4

1 回答 1

0

之所以不起作用,其实是一个简单的函数上的引用问题。

正如我们所使用return internalFunction()的,被引用的函数以真实的函数为目标,而sinon.stub(myModule, 'internalFunction')实际上在导出的函数中创建了一个引用。

然后让它工作,我们需要导出internalFunction并显式module.exports.internalFunction()使用externalFunction

// src/my-module.js

function externalFunction() {
  // note the use of module.exports here
  return module.exports.internalFunction();
}

function internalFunction() {
  return { omg: 'this is real' };
}

module.exports = {
  externalFunction,
  // note we export the internal function here
  internalFunction,
};
// test/my-module.spec.js

const { assert } = require('chai');
const {
  describe,
  it,
  before,
  beforeEach,
} = require('mocha');
const sinon = require('sinon');

let myModule;

describe('externalFunction', () => {
  before(() => {
    myModule = require('../src/my-module');
  });

  beforeEach(() => {
    // partial stubbing: it actually stubs the exported function
    sinon.stub(myModule, 'internalFunction').callsFake(() => ({ omg: 'this is fake' }));
  })

  it('returns the result of internalFunction', () => {
    const result = myModule.externalFunction();
    assert.deepEqual(result, { omg: 'this is fake' });
  });
});
于 2020-06-23T06:53:50.457 回答