Как бы я написал тест для чего-то, что использует стандартный вывод? - PullRequest
0 голосов
/ 07 декабря 2018

Я пытаюсь улучшить тестовое покрытие для этого файла

'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

Как мне написать тест, чтобы охватить этот код?

1 Ответ

0 голосов
/ 07 декабря 2018

Вы только утверждаете, что 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», чтобы проверить регистрируемый контент.

...