node.js - 如何在 Nodejs 中为 Winston 记录器编写单元测试

标签 node.js jestjs winston

我正在使用 winston logger 在 Nodejs 中编写一个日志框架。 现在我必须编写单元测试来使用 Jest 测试我的类。

下面是我的 LoggerClass:

'use strict';

const { createLogger, format, transports } = require('winston');

const fs = require('fs');
const env = process.env.NODE_ENV || 'development';

const logger = createLogger({
    level: env === 'development' ? 'debug' : 'info',
    format: format.combine(
        format.timestamp({
            format: 'YYYY-MM-DD HH:mm:ss'
        }),
        format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)),
    transports: [
        new transports.Console({
            level: 'info',
            format: format.combine(
                format.printf(
                    info => `${info.level}: ${info.message}`
                )
            )
        }),
        new transports.File({ filename })
    ]
});

module.exports = logger;

我将测试编写为:

const logger = require('./WinstonLogger');

global.console = {
    log: jest.fn(),
    info: jest.fn(),
    error: jest.fn(),
}

describe('Tests my console.log', () => {
    it('should console a message', () => {
        logger.info('Hello world');
        expect(global.console.log).toHaveBeenCalledWith(
            'info: Hello world'
        )
    })

})

如何修改我的测试?

最佳答案

这是单元测试解决方案:

logger.js:

'use strict';

const { createLogger, format, transports } = require('winston');

const env = process.env.NODE_ENV || 'development';
const filename = 'filename';

const logger = createLogger({
  level: env === 'development' ? 'debug' : 'info',
  format: format.combine(
    format.timestamp({
      format: 'YYYY-MM-DD HH:mm:ss',
    }),
    format.printf((info) => `${info.timestamp} ${info.level}: ${info.message}`),
  ),
  transports: [
    new transports.Console({
      level: 'info',
      format: format.combine(format.printf((info) => `${info.level}: ${info.message}`)),
    }),
    new transports.File({ filename }),
  ],
});

module.exports = logger;

logger.test.js:

jest.mock('winston', () => {
  const mFormat = {
    combine: jest.fn(),
    timestamp: jest.fn(),
    printf: jest.fn(),
  };
  const mTransports = {
    Console: jest.fn(),
    File: jest.fn(),
  };
  const mLogger = {
    info: jest.fn(),
  };
  return {
    format: mFormat,
    transports: mTransports,
    createLogger: jest.fn(() => mLogger),
  };
});
const { createLogger, format, transports } = require('winston');

describe('logger', () => {
  afterEach(() => {
    jest.resetAllMocks();
  });
  it('should pass', () => {
    let templateFunctions = [];
    format.printf.mockImplementation((templateFn) => {
      templateFunctions.push(templateFn);
    });
    const logger = require('./logger');
    logger.info('Hello world');
    const info = {
      timestamp: 123,
      level: 'info',
      message: 'haha',
    };
    const tFn1 = templateFunctions.shift();
    expect(tFn1(info)).toBe(`${info.timestamp} ${info.level}: ${info.message}`);
    const tFn2 = templateFunctions.shift();
    expect(tFn2(info)).toBe(`${info.level}: ${info.message}`);
    expect(format.combine).toBeCalledTimes(2);
    expect(format.timestamp).toBeCalledWith({ format: 'YYYY-MM-DD HH:mm:ss' });
    expect(format.printf).toBeCalledWith(expect.any(Function));
    expect(transports.Console).toBeCalledTimes(1);
    expect(transports.File).toBeCalledWith({ filename: 'filename' });
    expect(createLogger).toBeCalledTimes(1);
  });
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/59388359/logger.test.js (10.484s)
  logger
    ✓ should pass (10ms)

-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |      100 |       50 |      100 |      100 |                   |
 logger.js |      100 |       50 |      100 |      100 |               5,9 |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        11.789s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59388359

关于node.js - 如何在 Nodejs 中为 Winston 记录器编写单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59388359/

相关文章:

node.js - 如何使用 NodeJS 进行单点登录?

node.js - Nodejs winston 错过日志

javascript - 使用现有的 winston 记录器

javascript - 检查node.js服务器是否在线?

node.js - ENOSPC 设备上没有剩余空间 -Nodejs

javascript - 您如何使用 Jest 模拟 Firebase Firestore 方法?

javascript - 在单元测试中覆盖匿名函数参数

reactjs - 如何使用 Jest 和 Enzyme 模拟 React 组件生命周期方法?

javascript - 如何导入 NodeJS winston-daily-rotate-file 依赖项?

javascript - 无极 waterfall