我们有一个简单的快递应用程序。我们使用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
我们如何同时替换运输属性和createLogger?
我们需要能够模拟createLogger
的实现,然后才能在另一个测试中断言app.listen
已经使用logger.log和适当的参数进行了调用。
答案 0 :(得分:0)
尝试以下操作:
const mockCreateLogger = jest.fn().mockImplementation(() => {
log: jest.fn()
});
const mockConsole = jest.fn().mockImplementation(() => () => {});
jest.mock('winston', () => ({
createLogger: mockCreateLogger, // name must start with mock prefix
transports: {
Console: mockConsole // name must start with mock prefix
}
}));
// here import the file you are testing after the mocks
describe('logger', () => {
it('should create proper logger', () => {
expect(mockCreateLogger).toHaveBeenCalledWith({ transports: expect.anything() })
});
});
p.s。为了在此处正确编写单元测试,您还应该模拟express
以便在模拟的app
上工作,而不是导入“真实的”快递