如何在模拟函数内的模拟函数上编写测试?我想测试我的publish
模拟函数被调用一次。
jest.mock('amqplib', () => ({
connect: jest.fn(() => Promise.resolve({
createChannel: jest.fn(() => Promise.resolve({
assertExchange: jest.fn(),
publish: jest.fn(),
})),
close: jest.fn(),
})),
}));
我想测试的实际功能。
export default function (key, data, exchange = 'portal.topic', options = { type: 'topic' }) {
return amqp.connect(`amqp://${RABBITMQ_USER}:${RABBITMQ_PASS}@${RABBITMQ_URL}:${RABBITMQ_PORT}`).then(conn => {
conn.createChannel().then((ch) => {
ch.assertExchange(exchange, options.type, { durable: true });
ch.publish(exchange, key, Buffer.from(JSON.stringify(data)));
});
setTimeout(() => { conn.close(); }, 1000);
});
}
答案 0 :(得分:1)
首先,我建议根据您的逻辑从代码中删除setTimeout
,并且conn.createChannel
方法不会与外部诺言形成诺言链。更改后,单元测试:
index.js
:
import amqp from 'amqplib';
const RABBITMQ_USER = 'RABBITMQ_USER';
const RABBITMQ_PASS = 'RABBITMQ_PASS';
const RABBITMQ_URL = 'RABBITMQ_URL';
const RABBITMQ_PORT = 'RABBITMQ_PORT';
export default function(key, data, exchange = 'portal.topic', options = { type: 'topic' }) {
return amqp
.connect(`amqp://${RABBITMQ_USER}:${RABBITMQ_PASS}@${RABBITMQ_URL}:${RABBITMQ_PORT}`)
.then((conn) => {
return conn.createChannel().then((ch) => {
ch.assertExchange(exchange, options.type, { durable: true });
ch.publish(exchange, key, Buffer.from(JSON.stringify(data)));
return conn;
});
})
.then((conn) => conn.close());
}
index.test.js
:
import createChannel from './';
import amqp from 'amqplib';
describe('44922162', () => {
afterAll(() => {
jest.restoreAllMocks();
});
it('should create channel correctly', async () => {
const mCh = { assertExchange: jest.fn(), publish: jest.fn() };
const mConn = { createChannel: jest.fn().mockResolvedValueOnce(mCh), close: jest.fn() };
const connectSpy = jest.spyOn(amqp, 'connect').mockResolvedValueOnce(mConn);
const data = { payload: '123' };
await createChannel('key', data);
expect(connectSpy).toBeCalledWith('amqp://RABBITMQ_USER:RABBITMQ_PASS@RABBITMQ_URL:RABBITMQ_PORT');
expect(mConn.createChannel).toBeCalledTimes(1);
expect(mCh.assertExchange).toBeCalledWith('portal.topic', 'topic', { durable: true });
expect(mCh.publish).toBeCalledWith('portal.topic', 'key', Buffer.from(JSON.stringify(data)));
expect(mConn.close).toBeCalledTimes(1);
});
});
具有覆盖率报告的单元测试结果:
PASS src/stackoverflow/44922162/index.test.js (11.008s)
44922162
✓ should create channel correctly (7ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.js | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 12.335s
源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/44922162