我正试图为我的项目开发测试,我有一个连接到rabbitmq并消耗队列的文件,但我有问题要测试它
const amqp = require('amqplib/callback_api');
const rabbitConsumer = (io) => {
setTimeout(() => {
amqp.connect('amqp://rabbitmq', (error0, connection) => {
if (error0) {
throw error0;
}
connection.createChannel((error1, channel) => {
if (error1) {
throw error1;
}
const queue = 'message';
channel.assertQueue(queue, {
durable: false,
});
console.log(' [*] Waiting for message', queue);
channel.consume(
queue,
(data) => {
console.log(' [x] Received data:', data.content.toString('utf-8'));
io.emit('sendMessage', data.content.toString('utf-8'));
},
{
noAck: true,
}
);
});
});
}, 10000);
};
module.exports = rabbitConsumer;
是否可以测试这个文件?我如何使用JEST或任何其他库来做到这一点?
您可以使用jest。spyOn(object, methodName)创建模拟amqp
对象的方法。
使用jest.useFakeTimers(实现吗?: 'modern' | 'legacy')告诉jest使用假版本的setTimeout
函数,这样你就不需要等待真正的延迟时间。
使用jest.advanceTimersByTime(msToRun)来
当调用此API时,所有计时器都以msToRun毫秒为单位提前。所有挂起的"宏观任务"已经通过setTimeout()或setInterval()排队,并将在此时间范围内执行的任务将被执行
。
index.js
:
const amqp = require('amqplib/callback_api');
const rabbitConsumer = (io) => {
setTimeout(() => {
amqp.connect('amqp://rabbitmq', (error0, connection) => {
if (error0) {
throw error0;
}
connection.createChannel((error1, channel) => {
if (error1) {
throw error1;
}
const queue = 'message';
channel.assertQueue(queue, { durable: false });
console.log(' [*] Waiting for message', queue);
channel.consume(
queue,
(data) => {
console.log(' [x] Received data:', data.content.toString('utf-8'));
io.emit('sendMessage', data.content.toString('utf-8'));
},
{ noAck: true }
);
});
});
}, 10000);
};
module.exports = rabbitConsumer;
index.test.js
:
const amqp = require('amqplib/callback_api');
const rabbitConsumer = require('./');
describe('rabbitConsumer', () => {
beforeAll(() => {
jest.useFakeTimers();
});
afterAll(() => {
jest.useRealTimers();
});
test('should pass', () => {
const mData = {
content: 'teresa teng',
};
const mChannel = {
assertQueue: jest.fn(),
consume: jest.fn().mockImplementation((queue, callback) => {
callback(mData);
}),
};
const mConnection = {
createChannel: jest.fn().mockImplementation((callback) => {
callback(null, mChannel);
}),
};
jest.spyOn(amqp, 'connect').mockImplementation((url, callback) => {
callback(null, mConnection);
});
const mIO = {
emit: jest.fn(),
};
rabbitConsumer(mIO);
jest.advanceTimersByTime(10000);
expect(amqp.connect).toBeCalledWith('amqp://rabbitmq', expect.any(Function));
expect(mConnection.createChannel).toBeCalledWith(expect.any(Function));
expect(mChannel.assertQueue).toBeCalledWith('message', { durable: false });
expect(mChannel.consume).toBeCalledWith('message', expect.any(Function), { noAck: true });
});
});
测试结果:
PASS examples/69715530/index.test.js (21.564 s)
rabbitConsumer
✓ should pass (27 ms)
console.log
[*] Waiting for message message
at examples/69715530/index.js:15:17
console.log
[x] Received data: teresa teng
at channel.consume.noAck (examples/69715530/index.js:19:21)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 87.5 | 50 | 100 | 87.5 |
index.js | 87.5 | 50 | 100 | 87.5 | 7,11
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 23.222 s
您可以创建模拟错误,并将它们传递给模拟实现的callback
,以测试错误处理程序分支。