Catching console.log in node.js?

2019-02-04 15:19发布

Is there a way that I can catch eventual console output caused by console.log(...) within node.js to prevent cloggering the terminal whilst unit testing a module?

Thanks

4条回答
Animai°情兽
2楼-- · 2019-02-04 15:53

A better way could be to directly hook up the output you to need to catch data of, because with Linus method if some module write directly to stdout with process.stdout.write('foo') for example, it wont be caught.

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);
});

EDIT

console.log() ends its output with a newline, you may want to strip it so you'd better write:

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

EDIT

Improved, generic way to do this on any method of any object with async support See the gist.

查看更多
三岁会撩人
3楼-- · 2019-02-04 16:05

Simply add the following snippet to your code will let you catch the logs and still print it in the console:

var log = [];
console.log = function(d) {
    log.push(d);
    process.stdout.write(d + '\n');
};
查看更多
Evening l夕情丶
4楼-- · 2019-02-04 16:10

module.js:

module.exports = function() {
    console.log("foo");
}

program:

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

Edit: Obviously you can collect the log messages for later if you wish:

var log = [];
console.log = function() {
    log.push([].slice.call(arguments));
};
查看更多
ゆ 、 Hurt°
5楼-- · 2019-02-04 16:11

capture-console solves this problem nicely.

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
});

and later

Intercepting

You should be aware that all capture functions will still pass the values through to the main stdio write() functions, so logging will still go to your standard IO devices.

If this is not desirable, you can use the intercept functions. These functions are literally s/capture/intercept when compared to those shown above, and the only difference is that calls aren't forwarded through to the base implementation.

查看更多
登录 后发表回答