在node.js中捕获console.log?

Ind*_*ial 13 module callback node.js

有没有办法可以捕获console.log(...) node.js中的最终控制台输出,以防止在单元测试模块时堵塞终端?

谢谢

kev*_*vin 23

一种更好的方法是直接连接你需要捕获数据的输出,因为使用Linus方法,如果某些模块直接写入stdout,process.stdout.write('foo')例如,它就不会被捕获.

var logs = [],

hook_stream = function(_stream, fn) {
    // Reference default write method
    var old_write = _stream.write;
    // _stream now write with our shiny function
    _stream.write = fn;

    return function() {
        // reset to the default write method
        _stream.write = old_write;
    };
},

// hook up standard output
unhook_stdout = hook_stream(process.stdout, function(string, encoding, fd) {
    logs.push(string);
});

// goes to our custom write method
console.log('foo');
console.log('bar');

unhook_stdout();

console.log('Not hooked anymore.');

// Now do what you want with logs stored by the hook
logs.forEach(function(_log) {
    console.log('logged: ' + _log);
});
Run Code Online (Sandbox Code Playgroud)

编辑

console.log() 用换行符结束输出,你可能想要删除它,这样你最好写:

_stream.write = function(string, encoding, fd) {
    var new_str = string.replace(/\n$/, '');
    fn(new_str, encoding, fd);
};
Run Code Online (Sandbox Code Playgroud)

编辑

在具有异步支持的任何对象的任何方法上执行此操作的改进的通用方法请参阅要点.


Lin*_*iel 16

module.js:

module.exports = function() {
    console.log("foo");
}
Run Code Online (Sandbox Code Playgroud)

程序:

console.log = function() {};
mod = require("./module");
mod();
// Look ma no output!
Run Code Online (Sandbox Code Playgroud)

编辑:显然,如果您愿意,可以稍后收集日志消息:

var log = [];
console.log = function() {
    log.push([].slice.call(arguments));
};
Run Code Online (Sandbox Code Playgroud)


Mik*_*uel 5

capture-console很好地解决了这个问题。

var capcon = require('capture-console');

var stderr = capcon.captureStderr(function scope() {
  // whatever is done in here has stderr captured,
  // the return value is a string containing stderr
});

var stdout = capcon.captureStdout(function scope() {
  // whatever is done in here has stdout captured,
  // the return value is a string containing stdout
});
Run Code Online (Sandbox Code Playgroud)

然后

拦截

您应该知道所有capture函数仍会将值传递给主要的 stdiowrite()函数,因此日志记录仍将转到您的标准 IO 设备。

如果这不是您想要的,您可以使用这些intercept功能。s/capture/intercept与上面显示的函数相比,这些函数是字面上的,唯一的区别是调用不会转发到基本实现。