Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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'; 
like image 862
andimeier Avatar asked Mar 28 '14 10:03

andimeier


People also ask

Does console log affect performance Nodejs?

It greatly effects performance. I just did a test with console. log with 60,000 keys in my GAMES object. Then, simply did a for in to check if a property exists while console logging the GAMES object before checking.

What is the use of console log () method in node JS?

log() function from console class of Node. js is used to display the messages on the console. It prints to stdout with newline. Parameter: This function contains multiple parameters which are to be printed.


2 Answers

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.

like image 197
Dan Kohn Avatar answered Oct 08 '22 03:10

Dan Kohn


Here's a pretty simple solution that uses SinonJS's test stubs to suppress all console.log/info/warn/error statements before running your tests.

// my-method.js  export function myMethod() {     console.log(`I'm about to return true`)     return true } 

// my-method.test.js  import {describe, it, before} from 'mocha' import chai from 'chai' import sinon from 'sinon' import chalk from 'chalk' import {myMethod} from './my-method.js'  const expect = chai.expect  describe(chalk.underline('My Test Group'), () => {      before(() => {         sinon.stub(console, 'log')  // disable console.log         sinon.stub(console, 'info')  // disable console.info         sinon.stub(console, 'warn')  // disable console.warn         sinon.stub(console, 'error')  // disable console.error     })      describe('myMethod', () => {         it('should return true', () => {             expect(myMethod()).to.be.true  // without printing to the console         })     }) }) 

// output  My Test Group   myMethod     ✓ should return true 
like image 43
Derek Soike Avatar answered Oct 08 '22 03:10

Derek Soike