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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22709882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 17:05:30  来源:igfitidea点击:

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

node.jsunit-testingmocha

提问by andimeier

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.

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

I start the unit test with:

我开始单元测试:

mocha -R spec .

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

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

[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 wantwould be this output from the unit test:

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

  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?

如何抑制应用程序的 console.log/warn/error 输出,其中穿插着 Mocha 的报告器输出?

SOLUTION:

解决方案:

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

按照 dankohn 的方法,我最终得到了这样的结果,这解决了我的问题(使用winston进行日志记录):

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

(在节点的“主”服务器文件 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:

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

process.env.NODE_ENV = 'test';

采纳答案by Dan Kohn

In your app.js:

在你的 app.js 中:

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

At the top of each of your mocha files:

在每个 mocha 文件的顶部:

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.

然后,console.log('it worked')logExceptOnTest('it worked'). 基本技巧是使用环境变量作为您想要的日志记录级别的全局标志。

回答by Derek Soike

Here's a pretty simple solution that uses SinonJS's test stubsto suppress all console.log/info/warn/errorstatements before running your tests.

这是一个非常简单的解决方案,它使用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

回答by Justin Hamade

Already answered but thought I would add that you can do this user winston.add()

已经回答但我想我会补充说你可以做这个用户 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});
}