Can Winston logging be selectively disabled when executing unit tests of a node module?
Ideally, I'd like to have logging for informational and debug purposes when the application is running, but be suppressed as to not clutter the presentation unit test results when I run my tests.
My use of winston is internal to my module, something like this:
// 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
}
}
Create a logger:
Silence all logging:
Winston transports have a
silent
property that you can set, which is probably a little nicer than removing the entire transport.I add a name to the transports to make is a little easier like this:
Then in the test or set-up I can selectively turn logging on and off with:
Here's my setup:
The set up stuff did not work for me, I am using winston v3.1.0, there is a new way to create loggers.
From the winston site: https://github.com/winstonjs/winston
The recommended way to use winston is to create your own logger. The simplest way to do this is using winston.createLogger:
So I do this in my logger.js
This stops all log messages unless you have an error, which I would like to see to help with debugging any issues.
Hope this helps.
I realise that this is quite late but I just wanted to share my solution with using jest, since I wasn't entirely satisfied with the solutions found here. I can't say my solution is very elegant and may just be hiding some code smell as I'm still learning TDD, but it works.
In my work I often want to log to a file specified via a
winston.transports.File(filename: "<filename>")
transport. Let's say my log file isinfo.log
Of course, during testing, I don't want
info.log
info.log
to be created if it doesn't exist.This is so to avoid side-effects. The answers above along with mocking were enough for avoiding 1. but for some reason did not avoid 2. (explained why below) .
The way I set up my projects is usually as such
Focus mostly on the log-related files.
logger.js
is where I instantiate and subsequently export the winston Logger object. I then write helper functions inlogger_utils.js
for modularity and easier testing.When my issue was appearing,
logger.js
consisted inproblematic_logger.js
I then required it in
logger_utils.js
which would in turn be required in any other modules scripts. So, in testing (apart from testinglogger_utils.js
), I only need to mock functions contained inlogger_utils.js
, with no need to worry aboutlogger.js
, since it is only called bylogger_utils.js
.Now, I'm not entirely sure about this, but I think 2. defined above still failed despite the mocks and the silencing because
winston.createLogger()
was still being called, and I believe this will create a file even when a --silent flag is set. I don't know if this is true, but nevertheless the solutions above weren't working.So, (inspired by this answer) what I decided to do is to simply not create any winston object when testing. I did this by changing my
logger.js
file tofixed_logger.js
(
NODE_ENV
is automatically set to "test" when runningnpm test
ornpm run test:watch
etc.)We still need to export something for logger_utils.js to not break when testing it, so we export an empty object. This is fine since it will be mocked.
Anyway, that's my first answer on stackoverflow out of the way. I hope it wasn't too disastrous, let me know if anyone wants further details.
If you are using Jest, you can disable it like so:
Set set up files to be run before jest runs the test. In
package.json
:In
jest-set-up/index.js
: