使用Sinon解决Pino问题

问题描述

我正在尝试为服务函数编写单元测试,该函数在运行时返回Pino日志消息。我已经通过 service.js 中使用的记录器模块,使用Sinon构建了一个存根,但是未能获得成功的测试。测试返回: AssertionError:预期错误已被精确调用过一次,但被调用0次

理想情况下,我希望能够断言记录器已被调用,并且该函数返回了确切的记录器调用和消息。

下面是一些我想要实现的示例代码

logger.js

const pino = require('pino');

const defaultLogger = pino({},'output.log');


module.exports = {
  defaultLogger
}

service.js

const path = require('path');
const { defaultLogger } = require('../common/logger');
const logger = defaultLogger.child({ filename: path.basename(__filename) });

const logResponse = () => {
  return logger.info('successful');
};

service.test.js

const sinon = require('sinon');
const chai = require('chai');
const sinonChai = require('sinon-chai');
const service = require('../service.js')
const { defaultLogger } = require('../common/logger');
const { expect } = chai;
chai.should();
chai.use(sinonChai);

describe('Service Test',() => {
  it('should return a log message',() => {
    const spy = sinon.spy(service,'logResponse')
    const stub = sinon.stub(defaultLogger,'error');
    spy.should.have.been.calledOnce;
    expect(stub).to.have.been.calledOnce;
    spy.should.have.returned(logger.info('successful'));
  })
})

解决方法

这是单元测试解决方案:

./logger.js

const pino = require('pino');

const defaultLogger = pino({},'output.log');

module.exports = {
  defaultLogger,};

./service.js

const path = require('path');
const { defaultLogger } = require('./logger');
const logger = defaultLogger.child({ filename: path.basename(__filename) });

const logResponse = () => {
  return logger.info('successful');
};

module.exports = {
  logResponse,};

./service.test.js

const { defaultLogger } = require('./logger');
const sinon = require('sinon');
const chai = require('chai');
const { expect } = chai;

describe('63618186',() => {
  it('should return a log message ',() => {
    const loggerStub = {
      info: sinon.stub().returns('anything'),};
    sinon.stub(defaultLogger,'child').returns(loggerStub);
    const service = require('./service');
    const actual = service.logResponse();
    expect(actual).to.be.equal('anything');
    sinon.assert.calledOnce(defaultLogger.child);
    sinon.assert.calledWithExactly(loggerStub.info,'successful');
  });
});

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

  63618186
    ✓ should return a log message 


  1 passing (41ms)

------------|---------|----------|---------|---------|-------------------
File        | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------|---------|----------|---------|---------|-------------------
All files   |     100 |      100 |     100 |     100 |                   
 logger.js  |     100 |      100 |     100 |     100 |                   
 service.js |     100 |      100 |     100 |     100 |                   
------------|---------|----------|---------|---------|-------------------

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...