有时,在一个模块中,函数调用其他函数(用于分解、代码抽象等(,我们可能希望在不测试内部函数的情况下测试调用者函数。
但是,此代码不能按原样工作:
// 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' });
});
});
它不起作用的原因实际上是对函数的引用的简单问题。
正如我们使用return internalFunction()
,引用的函数针对真实的函数,而sinon.stub(myModule, 'internalFunction')
实际上在导出的函数中创建引用。
然后要让它工作,我们需要导出internalFunction
并在externalFunction
中显式使用module.exports.internalFunction()
// 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' });
});
});