【发布时间】:2019-06-15 23:46:39
【问题描述】:
我们有一个简单的快递应用。我们使用 winston 作为第三方来正确处理日志记录。
const express = require('express');
const app = express();
const { createLogger, transports } = require('winston');
const port = process.env.PORT || 5000;
const logger = createLogger({ transports: [ new transports.Console()] });
const { catchAll } = require('./routes/catchall');
app.get('*', catchAll);
app.listen(port, () => logger.log({ level: 'info', message: `server listening on port ${port}!` }));
我们希望,在我们的单元测试中,检查 createLogger 是否已使用正确的参数调用。
我们一开始只尝试使用jest.mock('winston),但开玩笑地抱怨TypeError: transports.Console is not a constructor。
然后我们尝试使用以下方法手动模拟包:
let { createLogger, transports } = require('winston');
const consoleClass = class Console{};
jest.doMock('winston', () => {
return {
createLogger: jest.fn(),
transports: {
Console: consoleClass
}
}
});
describe('logger', () => {
it('should create proper logger', () => {
expect(createLogger).lastCalledWith({ transports: [ new transports.Console()] })
});
});
关于控制台的错误消失了。但是我们的测试失败了:
logger › should create proper logger
expect(jest.fn())[.not].lastCalledWith()
jest.fn() value must be a mock function or spy.
Received:
function: [Function anonymous]
39 | describe('logger', () => {
40 | it('should create proper logger', () => {
> 41 | expect(createLogger).lastCalledWith({ transports: [ new transports.Console()] })
| ^
42 | });
43 | });
44 |
at Object.lastCalledWith (tests/app.spec.js:41:26)
我们尝试在doMock之后添加
createLogger.mockImplementation(() => {});
但它抱怨TypeError: createLogger.mockImplementation is not a function
如何同时替换 transports 属性和 createLogger?
我们需要能够模拟 createLogger 的实现,然后才能在另一个测试中断言 app.listen 已使用 logger.log 和适当的参数调用。
【问题讨论】:
标签: javascript node.js jestjs winston