我有一个模块,不应该直接从Node命令行调用。为此,我将主模块检查为indicated in the documentation:
if (require.main === module) {
console.error('This module cannot be run from the command line.');
} else {
// Here the module logic...
}
现在我正在为这个模块编写单元测试(如果重要的话,使用Mocha / Chai),我想模拟直接从命令行调用模块的情况,当错误应该打印到stderr时。
其余的逻辑已经在测试中,但我无法通过单元测试获得require.main === module
分支。我用最简洁的方法来解决这个问题就是在模块内部模拟require.main
,但我不知道如何做到这一点。我们已经使用proxyquire来模拟依赖项,但在这种情况下它没有帮助。
有关如何处理此问题的任何建议吗?
答案 0 :(得分:1)
已经3年了,但是我可以模拟这种情况。
概念:存根/模拟在require.main
和module
之间进行比较的比较功能。
在下面的示例中:我使用以下模块:重接线,sinon,chai,mocha和nyc。
有这个index.js
// File: index.js (original)
if (require.main === module)) {
console.log('Run directly');
} else {
console.log('Run NOT directly');
}
我创建了一个包含用于比较2个输入的函数的帮助器。
// File: helper.js
function runDirectly(a, b) {
// Suppose:
// a: require.main
// b: module
return (a === b);
}
module.exports = { runDirectly };
然后我将索引修改为类似的内容。
// File: index.js (modified)
const helper = require('./helper.js');
if (helper.runDirectly(require.main, module)) {
console.log('Run directly');
} else {
console.log('Run NOT directly');
}
当我直接从命令行尝试时,它仍然可以正常运行。
$ node index.js
Run directly
$
我创建了这个规范文件。
// File: index.spec.js
const rewire = require('rewire');
const sinon = require('sinon');
const { expect } = require('chai');
const helper = require('./helper.js');
describe('Index', function () {
let sandbox;
before(function () {
sandbox = sinon.createSandbox();
});
afterEach(function () {
sandbox.restore();
});
it('simulate run directly', function () {
const stubHelperRunDirectly = sandbox.stub(helper, 'runDirectly');
// Simulate require.main === module.
stubHelperRunDirectly.returns(true);
const stubConsoleLog = sandbox.stub(console, 'log');
rewire('./index.js');
expect(stubHelperRunDirectly.calledOnce).to.equal(true);
expect(stubConsoleLog.calledOnce).to.equal(true);
expect(stubConsoleLog.args[0][0]).to.equal('Run directly');
});
it('simulate run NOT directly', function () {
const stubHelperRunDirectly = sandbox.stub(helper, 'runDirectly');
// Simulate: require.main !== module.
stubHelperRunDirectly.returns(false);
const stubConsoleLog = sandbox.stub(console, 'log');
rewire('./index.js');
expect(stubHelperRunDirectly.calledOnce).to.equal(true);
expect(stubConsoleLog.calledOnce).to.equal(true);
expect(stubConsoleLog.args[0][0]).to.equal('Run NOT directly');
});
});
然后,当我进行测试和覆盖时,这里是结果。
$ npx nyc mocha index.spec.js
Index
✓ simulate run directly
✓ simulate run NOT directly
2 passing (45ms)
---------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
---------------|---------|----------|---------|---------|-------------------
All files | 96.77 | 100 | 83.33 | 96.77 |
helper.js | 50 | 100 | 0 | 50 | 10
index.js | 100 | 100 | 100 | 100 |
index.spec.js | 100 | 100 | 100 | 100 |
---------------|---------|----------|---------|---------|-------------------
$
现在index.js具有100%的覆盖率,并且helper.js易于测试。 :)