【问题标题】:Can I mock console in NodeJs?我可以在 NodeJs 中模拟控制台吗?
【发布时间】:2015-06-10 17:23:16
【问题描述】:
在我的 JS 测试中,我需要检查是否调用了 console.info。这就是我想模拟控制台的原因。但是,似乎不能为控制台变量分配不同的对象。我有没有搞错?
这是我使用的代码:
var oldConsole = console;
var infoContent;
console = {
info: function(content) {
infoContent = content;
}
};
game.process('a command');
infoContent.should.equal('a command is processed');
console = oldConsole;
【问题讨论】:
标签:
javascript
node.js
testing
console
mocking
【解决方案1】:
我找到了解决办法。我可以更改控制台的方法信息。
console.info = function(content) {
infoContent = content;
};
现在的问题是为什么控制台对象本身不能被重新分配?
【解决方案2】:
您可以使用sinon npm 来计算对函数的调用:
it("calls the original function only once", function () {
var callback = sinon.spy();
var proxy = once(callback);
proxy();
proxy();
assert(callback.calledOnce);
// ...or:
// assert.equals(callback.callCount, 1);
});
您可以在此处找到文档:sinonjs.org
【解决方案3】:
您可以使用rewire 替换整个控制台以使其静音,或注入模拟。我使用deride,但 sinon 也可以。
var rewire = require('rewire');
var deride = require('deride');
var Game = rewire('../lib/game');
describe('game testing', function() {
var stubConsole, game;
beforeEach(function() {
stubConsole = deride.stub(['info']);
stubConsole.setup.info.toReturn();
Game.__set__({
console: stubConsole
});
game = new Game();
});
it('logs info messages', function() {
game.process('a command');
stubConsole.expect.info.called.withArgs(['a command is processed']);
});
});
【解决方案4】:
我以为我遇到了同样的问题,我的解决方案是使用这个 std-mocks 模块:
这具有不接管全局“控制台”的优点,但允许您查看记录到 stdout/stderr 的内容。这以不同于问题明确寻找的方式解决了问题;但是我相信这是问题所暗示的问题的一个很好的答案,并且可能对其他人有用。
const stdMocks = require('std-mocks');
stdMocks.use(); console.log('test'); stdMocks.restore();
// => undefined [nothing gets output, stdout intercepted]
const logged = stdMocks.flush();
console.log(logged)
// => { stdout: [ 'test\n' ], stderr: [] }