Отключить ведение журнала Winston при выполнении модульных тестов?
Можно ли выборочно отключить ведение журнала Winston при выполнении модульных тестов модуля node?
В идеале, я хотел бы иметь журнал для информационных и отладочных целей, когда приложение работает, но будет подавлено, чтобы не загромождать результаты презентации unit test при выполнении моих тестов.
Мое использование winston является внутренним для моего модуля, что-то вроде этого:
// MyModule.js
var logger = require('winston');
module.exports = function() {
// does some stuff
// and logs some stuff like so:
logger.log('an informational message');
}
// MyModuleTest.js
describe('MyModule', fucntion() {
it('should do some stuff', function() {
var myModuleUnderTest = require('MyModule');
// some tests
}
}
Ответы
Ответ 1
У транспортных средств Winston есть свойство silent
, которое вы можете установить, что, вероятно, немного лучше, чем удаление всего транспорта.
Я добавляю имя в транспорты, чтобы сделать это немного проще:
var logger = new winston.Logger();
logger.add(winston.transports.Console, {
name: 'console.info',
colorize: true,
showLevel: true,
formatter: consoleFormatter,
})
Затем в тесте или настройке я могу выборочно включать и отключать ведение журнала с помощью:
logger.transports['console.info'].silent = true // turns off
logger.transports['console.info'].silent = false // logging back on
Ответ 2
Если вы используете Jest, вы можете отключить его так:
-
Установите настройки файлов, которые должны быть запущены до того, как jest запускает тест. В package.json
:
{
"jest": {
"setupFiles": ["<rootDir>/jest-set-up/index.js"]
}
}
-
В jest-set-up/index.js
:
import winston from 'winston'
winston.remove(winston.transports.Console)
Ответ 3
Извините, я знаю, что это немного старый вопрос.
То, что я делаю, немного уродливо, но позволяет мне обычно использовать параметр Jest --silent
. Я просто установил Winston silent
в process.argv.indexOf("--silent") >= 0
. Например:
const logger = new winston.Logger({
…,
transports: [
new winston.transports.Console({
…,
silent: process.argv.indexOf("--silent") >= 0,
}),
],
});
Ответ 4
Создать регистратор:
const logger = createLogger({
level: "info",
format: format.json(),
transports: []
});
Тишина всех логов:
logger.transports.forEach((t) => (t.silent = true));
Ответ 5
Вот моя настройка:
const { createLogger, format, transports, config } = require("winston");
let level, silent;
switch (process.env.NODE_ENV) {
case "production":
level = "warning";
silent = false;
break;
case "test":
level = "emerg";
silent = true;
break;
default:
level = "debug";
silent = false;
break;
}
const options = {
console: {
level,
silent,
handleExceptions: true,
format: format.combine(
format.colorize(),
format.splat(),
format.printf(
info => '${new Date().toISOString()} ${info.level}: ${info.message}',
),
),
},
};
const logger = createLogger({
levels: config.syslog.levels,
transports: [new transports.Console(options.console)],
exitOnError: false,
});
module.exports = logger;
Ответ 6
У меня не сработали настройки, я использую Winston v3.1.0, есть новый способ создания регистраторов.
С сайта Уинстон: https://github.com/winstonjs/winston
Рекомендуемый способ использовать winston - создать свой собственный регистратор. Самый простой способ сделать это - использовать winston.createLogger:
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
//
// - Write to all logs with level 'info' and below to 'combined.log'
// - Write all logs error (and below) to 'error.log'.
//
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' })
]
});
//
// If we're not in production then log to the 'console' with the format:
// '${info.level}: ${info.message} JSON.stringify({ ...rest }) '
//
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.simple()
}));
}
Так что я делаю это в моем logger.js
if (process.env.NODE_ENV === 'test') {
return winston.createLogger({
transports: [ new winston.transports.Console({ level: 'error'}) ]
});
}
Это останавливает все сообщения журнала, если у вас нет ошибки, которую я хотел бы видеть, чтобы помочь с отладкой любых проблем.
Надеюсь это поможет.
Ответ 7
Я понимаю, что уже довольно поздно, но я просто хотел поделиться своим решением с использованием Jest, так как я не был полностью удовлетворен решениями, найденными здесь. Я не могу сказать, что мое решение очень элегантное и, возможно, просто скрывает некоторый запах кода, поскольку я все еще изучаю TDD, но оно работает.
В своей работе я часто хочу войти в файл, указанный с помощью транспорта winston.transports.File(filename: "<filename>")
. Допустим, мой файл журнала info.log
Конечно, во время тестирования я не хочу
- журналы, которые будут записаны в этот
info.log
info.log
должен быть создан, если он не существует.
Это так, чтобы избежать побочных эффектов. Ответов, приведенных выше, вместе с насмешками было достаточно, чтобы избежать 1., но по какой-то причине не избежать 2. (объясняется почему ниже).
Как я обычно настраиваю свои проекты,
src
├── app.js
├── services
│ ├── logging
│ │ ├── logger.js
│ │ └── logger_utils.js
│ ├── foo.js
│ ├── bar.js
│ └── etc.js
├── tests
│ ├── foo.test.js
│ ├── bar.test.js
│ └── etc.test.js
└── logs
└── info.log
Сосредоточьтесь в основном на файлах, связанных с журналом. logger.js
- это место, где я создаю экземпляр и затем экспортирую объект Winston Logger. Затем я пишу вспомогательные функции в logger_utils.js
для модульности и упрощения тестирования.
Когда появилась моя проблема, logger.js
состоял в
problematic_logger.js
const winston = require("winston");
const path = require("path");
// define the log file directory
const log_dir = path.resolve(__dirname, "./../../logs/info.log");
// create logger
const logger = winston.createLogger({
transports: [
new winston.transports.File({
filename: log_dir
})
]
});
// export it
module.exports = logger;
Затем я потребовал это в logger_utils.js
, что, в свою очередь, потребовалось бы для любых других скриптов модулей. Итак, при тестировании (кроме тестирования logger_utils.js
) мне нужно только смоделировать функции, содержащиеся в logger_utils.js
, и не нужно беспокоиться о logger.js
, поскольку он вызывается только logger_utils.js
.
Теперь я не совсем уверен в этом, но я думаю, что 2. определенный выше все еще не удался, несмотря на насмешки и глушение, потому что winston.createLogger()
все еще вызывался, и я считаю, что это создаст файл, даже когда флаг --silent установлено. Я не знаю, правда ли это, но, тем не менее, приведенные выше решения не сработали.
Итак, (вдохновленный этим ответом) я решил просто не создавать объект winston при тестировании. Я сделал это, изменив файл logger.js
на
fixed_logger.js
const winston = require("winston");
const path = require("path");
// define the log file directory
const log_dir = path.resolve(__dirname, "../../logs/info.log");
// if we are testing, don't create any winston object
if (process.env.NODE_ENV === "test") {
// export
module.exports = {};
} else {
// behave normally otherwise
// create winston logger
const logger = winston.createLogger({
transports: [
new winston.transports.File({
filename: log_dir
})
]
});
// export it
module.exports = logger;
}
(NODE_ENV
автоматически устанавливается на "тест" при запуске npm test
или npm run test:watch
и т.д.)
Нам все еще нужно экспортировать что-то, чтобы logger_utils.js не сломался при тестировании, поэтому мы экспортируем пустой объект. Это хорошо, так как это будет издеваться.
Во всяком случае, это мой первый ответ на stackoverflow из пути. Я надеюсь, что это не было слишком пагубно, дайте мне знать, если кто-то хочет получить более подробную информацию.