javascript - 我将如何为使用标准输出的东西编写测试?

标签 javascript node.js unit-testing mocha.js bunyan

我正在尝试提高此文件的测试覆盖率

'use strict'

/**
 * Returns the logging options we're using
 *
 * @param   {String} name Name of the logger. Should be service name. e.g. ciitizen-file-service
 * @returns {Object}      The logging options we're using
 * @private
 */
function getLoggerOptions(name) {
  return {
    name: name,
    streams: [
      {
        level: 'info',
        stream: stdOutStream()
      }, {
        level: 'error',
        stream: stdErrStream()
      }
      , {
        level: 'debug',
        stream: stdOutStream()
      },
      {
        level: 'warn',
        stream: stdOutStream()
      },
      {
        level: 'fatal',
        stream: stdErrStream()
      }
    ]
  }
}

/**
 * Creates a stream that writes to stdout
 *
 * @param   {Object} info The log info
 * @returns {Object}      An object which logs to stdout
 * @private
 */
function stdOutStream() {
  return {
    write: log => {
      // Change log level number to name and write it out
      log.level = bunyan.nameFromLevel[log.level]
      process.stdout.write(JSON.stringify(log) + '\n')
    }
  }
}

/**
 * Creates a stream that writes to stderr
 *
 * @param   {Object} info The log info
 * @returns {Object}      An object which logs to stderr
 * @private
 */
function stdErrStream() {
  return {
    write: log => {
      // Change log level number to name and write it out
      log.level = bunyan.nameFromLevel[log.level]
      process.stderr.write(JSON.stringify(log) + '\n')
    }
  }
}

module.exports = { getLoggerOptions }

我目前有这个测试

'use strict'

const expect = require('chai').expect
const { getLoggerOptions } = require('../src/helpers')

describe.only('#getLoggerOptions', () => {
  it('should return the logger options', () => {
    expect(getLoggerOptions('test')).to.be.an('object')
  })
})

这会导致单元测试覆盖率出现差距 enter image description here

我如何编写测试来覆盖这段代码?

最佳答案

您只是断言 getLoggerOptions(...) 应该返回一个对象,但您并未访问该对象。

例如,除了发布的测试之外,尝试添加如下测试:

describe.only('#probeLoggerOptions', () => {
  it('should do expected logging stuff', () => {
    const {name, streams} = getLoggerOptions('test');
    for (let stream of streams) {
      console.log(`getting logopt for level ${stream.level}`);
      expect(stream.stream.write(log), /* ... what to expect */);
    }
  });
});

现在测试正在调用每个对象中的write 函数。

额外:如果您拥有代码,最好的方法是重构它以使其更易于测试。例如,不是直接写入高级 process 流,而是创建一个 WritableStream,写入它,然后通过管道传输到所需的 process 流。

function configureStream(writable = process.stdout, data = null, msg = 'done') {
  const stream = fs.createReadStream('/tmp/log');
  stream.read(data);
  stream.pipe(writable);

function stdOutStream() {
  return {
    write: log => {
      // Change log level number to name and write it out
      log.level = bunyan.nameFromLevel[log.level];
      configureStream(data = JSON.stringify(log) + '\n');
    }
  }
}

除了能够单独测试 configureStream 之外,您还可以将每个日志记录过程的内容抽象为一个函数,以减少测试面。现在,您还可以连接到流的事件(如“pipe”或“finish”)以检查正在记录的内容。

关于javascript - 我将如何为使用标准输出的东西编写测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53673797/

相关文章:

javascript - 通过修改Three.JS中 "Line"的属性,在canvas中绘制并定位 "Line"

node.js - Express 参数化路由冲突

angular - 模拟 Angular Material Dialog afterClosed() 用于单元测试

javascript - 在 Jasmine 的规范中包含 backbone.js

javascript - Bootstrap Selectpicker - noneResultsText 不适用于 optgroup

javascript - 动态创建贝塞尔曲线?

node.js - 不将数据从服务方法传递到 mongoose get 路由以使用 Angular IO 查询数据

c# - 单元测试断言的最佳实践

javascript - 如何通过将对象键输入函数参数来打印对象值?

javascript - Node.js:如何为 prod 和 staging 设置不同的变量