在测试中加载模块时,如何使用 Jest 来测试将 pino 调试日志写入标准输出?



我正在使用pino作为记录器,并将输出发送到标准输出目的地。我正在尝试测试调试消息是否写入标准输出,但在测试中看不到写入 process.stdout 的任何内容......谁能帮忙?

皮诺记录仪

'use strict'
const pino = require('pino')
const log = pino({ name: 'TensorFlow-WithFiltering-And-MQTT', level: 'debug' }, pino.destination(1))
module.exports = {
parentLogger: log
}

被测代码

const { parentLogger, Process } = require('./libs/utils/src')
const log = parentLogger.child({ module: 'child_process' })
/** main function that spawns process is here */
/** 
Want to test that the promise resolves and the debug message is written to stdout when it resolves. 
In VSCode it is hitting the breakpoint in the then block and can see that it resolves
but the test included below fails
**/
main()
.then(() => {
log.debug('notify.js process finished initialising')
})
.catch((error) => {
log.error(`notify.js process failed to initialise := ${error}`)
})

当前开玩笑测试

test.only('main function resolves promise and logs debug message', () => {
const args = [
'node',
'notify.js',
`mqtts://${global.config.user}:${global.config.user}@${global.config.host}:8883`,
`${__dirname}/../../docker/certs/localCA.crt`,
5000,
'false'
]
/** pino logger writes to stdout - trying to check what is written to stdout stream **/
let logged = ''
process.stdout._orig_write = process.stdout.write
process.stdout.write = (data) => {
logged = logged + data
process.stdout._orig_write(data)
}
const oldArgs = process.argv
process.argv = args
const notify = require('../../../src/notify')
try {
expect(logged).toEqual('notify.js process finished initialising')
} finally {
process.argv = oldArgs
process.stdout.write = process.stdout._orig_write
}
})

pino.destination是在音爆上实现的,这个库正在管理流。请参阅文档。

不知何故,它可以在您的应用程序process.stdout工作,因此替换write函数不会捕获日志标准输出。

您可以通过替换可从记录器访问的SonicBoom流write来访问它。如果你可以公开你的log,所以它可以导入到测试文件中 - 你可以这样使用它:

溶液

/* Import log. Better to define it in another file, then import to both main and test. */
const { log } = require('../../../src/notify');
// Import stream symbol
const { streamSym } = require('pino/lib/symbols');

test.only('main function resolves promise and logs debug message', () => {
const args = [
'node',
'notify.js',
`mqtts://${global.config.user}:${global.config.user}@${global.config.host}:8883`,
`${__dirname}/../../docker/certs/localCA.crt`,
5000,
'false'
]
let logged = ''
log[streamSym]._orig_write = log[streamSym].write
process.stdout.write = (data) => {
logged = logged + data
process.stdout._orig_write(data)
}
const oldArgs = process.argv
process.argv = args
const notify = require('../../../src/notify')
try {
expect(logged).toEqual('notify.js process finished initialising')
} finally {
process.argv = oldArgs
log[streamSym].write = log[streamSym]._orig_write
}
})

间谍版本

更好的是使用jest.spyOn

/* Import log. Better to define it in another file, then import to both main and test. */
const { log } = require('../../../src/notify');
// Import stream symbol
const { streamSym } = require('pino/lib/symbols');

let stdoutSpy, oldArgs;
const args = [
'node',
'notify.js',
`mqtts://${global.config.user}:${global.config.user}@${global.config.host}:8883`,
`${__dirname}/../../docker/certs/localCA.crt`,
5000,
'false'
];
beforeAll(() => {
stdoutSpy = jest.spyOn(log[streamSym], 'write');
oldArgs = process.argv
process.argv = args
})
afterAll(() => {
process.argv = oldArgs
stdoutSpy.mockRestore();
})
test.only('main function resolves promise and logs debug message', () => {
const notify = require('../../../src/notify')
expect(stdoutSpy).toHaveBeenCalledWith('notify.js process finished initialising');
})

最新更新