andimeier andimeier - 5 months ago 177
Node.js Question

How to suppress application logging messages from a node.js application when running unit tests?

While unit-testing my node.js application (which is basically a REST backend) using mocha and supertest, I need only the test-specific message on the screen, but the stdout is also cluttered with application log messages.

I start the unit test with:

mocha -R spec .


... and get this output (this is what it should not be):

[App] Listening on port 3000 ...
[App] Starting app, hooray!

Project API
GET /projects
[App] entering "projects" module ...
√ should return an array of projects (317ms)


I marked the application log message with [App]. What I really want would be this output from the unit test:

Project API
GET /projects
√ should return an array of projects (317ms)


How can I suppress console.log/warn/error output by the application interspersed with Mocha's reporter output?

SOLUTION:

Following dankohn's approach, I ended up like this, which solves my issue (using winston for logging):

(in node's "main" server file, server.js:)

if (process.env.NODE_ENV !== 'test') {
logger = new (winston.Logger)({
transports: [
new (winston.transports.Console)(),
new (winston.transports.File)({ filename: 'foo.log' })
]
});
} else {
// while testing, log only to file, leaving stdout free for unit test status messages
logger = new (winston.Logger)({
transports: [
new (winston.transports.File)({ filename: 'foo.log' })
]
});
}


... and to set the env variable, each unit test file starts with:

process.env.NODE_ENV = 'test';

Answer

In your app.js:

if (process.env.NODE_ENV !== 'test') {
  app.use(express.logger());
}

At the top of each of your mocha files:

process.env.NODE_ENV = 'test';

Update:

We use this function in our import code:

function logExceptOnTest(string) {
  if (process.env.NODE_ENV !== 'test') {
    console.log(string);
  }
}

Then, replace all your console.log('it worked') with logExceptOnTest('it worked'). The basic trick is to use environment variables as a global flag as to the level of logging you want.