'jest winston format.errors is not a function
I have an app that uses winston for logging. I am trying to setup a jest test for a function, that calls another function, etc., and the test for the function eventually fails at an attempt to use winston exported functions:
services\__tests__>jest search.test.js
FAIL ./search.test.js
● Test suite failed to run
TypeError: format.errors is not a function
26 | const logger = createLogger({
27 | level: config.logging.level,
> 28 | format: format.combine(format.errors({ stack: true }), errorStackFormat(), config.logging.logFormat()),
| ^
29 | transports: [
30 | new transports.Console({
31 | stderrLevels: ['error', 'critical'],
at Object.<anonymous> (helpers/logger.js:28:33)
at Object.<anonymous> (db/connection/connection.js:2:16)
/search.test.js
jest.mock('winston', () => ({
format: jest.fn(() => ({
errors: jest.fn(),
combine: jest.fn(),
apply: jest.fn(),
})),
createLogger: jest.fn().mockImplementation(() => ({
info: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
})),
transports: {
Console: jest.fn(),
},
}));
const search = require('../search');
process.env.NODE_ENV = 'development';
describe('services/search.js', () => {
it('searches ', async () => {
const query = {
mpn: '5555555555',
};
expect(
await search(query).then((result) => {
console.log('result', result);
return result;
})
).toEqual(['000']);
});
});
helpers/logger.js
const { createLogger, format, transports } = require('winston');
const config = require('../config');
require('express-async-errors');
const errorStackFormat = format((info) => {
if (info.level === 'error') {
if (!/^{.*?}$/.test(info.message)) return info;
const { code, reason, status, message } = JSON.parse(info.message);
return {
...info,
code,
reason,
status,
message,
};
}
return info;
});
const logger = createLogger({
level: config.logging.level,
format: format.combine(format.errors({ stack: true }), errorStackFormat(), config.logging.logFormat()),
transports: [
new transports.Console({
stderrLevels: ['error', 'critical'],
}),
],
exceptionHandlers: [new transports.Console(config.logging.format)],
exitOnError: true,
});
module.exports = logger;
If I try to only have format as an object, it fails the test on const errorStackFormat = format((info) because it's looking for format to be a function, so the mock needs to have format as a function, and also have properties (like errors) that are functions as well.
How can I get format.errors to work in the mock? I'm not doing something right, please help me figure out what I am doing wrong :) Thanks!
Solution 1:[1]
Well I figured it out, at least it's not complaining anymore about the original error. I needed to use my logger function that uses winston, like so:
jest.mock('../../helpers/logger', () => jest.fn());
const logger = require('../../helpers/logger');
logger.mockImplementation(() => () => ({
format: jest.fn(() => ({
errors: jest.fn(),
combine: jest.fn(),
apply: jest.fn(),
})),
createLogger: jest.fn().mockImplementation(() => ({
info: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
})),
transports: {
Console: jest.fn(),
},
}));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Kris Nelson |
