如何在Node.js中为Winston logger编写单元测试

时间:2019-12-18 08:46:22

标签: node.js jestjs winston

我正在使用Winston logger在Nodejs中编写日志记录框架。 现在,我必须编写单元测试以使用玩笑来测试我的课程。

下面是我的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'
        )
    })

})

我如何修改考试?

1 个答案:

答案 0 :(得分:1)

这是单元测试解决方案:

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