在运行单元测试时,如何抑制来自node.js应用程序的应用程序日志消息?

在使用mocha和supertest对我的node.js应用程序(基本上是REST后端)进行单元测试时,我只需要屏幕上特定于测试的消息,但标准输出也被应用程序日志消息所困扰。

我从以下单元测试开始:

mocha -R spec .

...并获得此输出(这是不应该的):

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

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

我用[App]标记了应用程序日志消息。 我真正想要的是单元测试的输出:

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

我如何抑制应用程序插入Mocha的报告程序输出的console.log / warn / error输出?

解:

遵循dankohn的方法,我最终像这样解决了我的问题(使用Winston进行日志记录):

(在节点的“主”服务器文件中,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' })
        ]
    });
}

...并设置env变量,每个单元测试文件都以:

process.env.NODE_ENV = 'test';
andimeier asked 2020-01-14T13:47:35Z
3个解决方案
34 votes

在您的app.js中:

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

在每个mocha文件的顶部:

process.env.NODE_ENV = 'test';

更新:

我们在导入代码中使用此功能:

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

然后,将所有console.log('it worked')替换为logExceptOnTest('it worked')。基本技巧是使用环境变量作为所需标志级别的全局标志。

Dan Kohn answered 2020-01-14T13:48:13Z
7 votes

已经回答,但以为我会补充说明,您可以执行此用户winston.add()

var logger = new (winston.Logger)({
    transports: [
        new (winston.transports.File)({filename: 'node.log'})
    ]
});

if (process.env.NODE_ENV === 'test') {
    logger.add(winston.transports.Console, {prettyPrint: true});
}

Justin Hamade answered 2020-01-14T13:48:38Z
5 votes

这是一个非常简单的解决方案,在运行测试之前,使用SinonJS的测试存根抑制所有console.log/info/warn/error语句。

// 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
Derek Soike answered 2020-01-14T13:48:58Z
translate from https://stackoverflow.com:/questions/22709882/how-to-suppress-application-logging-messages-from-a-node-js-application-when-run