我正在测试一个 Nodejs 进程,它从 Redis 队列中读取数据,执行一些操作,将输出推送到另一个 Redis 队列中。
为了黑盒测试此过程,我对数据库和缓存使用各种模拟,但保留所有逻辑不变。特别是,当 lpush 到输出队列时,redis 的模拟确实会发出一个事件。我的希望是在 test() 中捕获该事件并执行我的检查。
问题是整个事情“有效”,事件被触发,在 test() 内捕获,并且值在那里并且它们也是正确的,但我无法设法让测试结束。在各种尝试中,我什至得到了永远不会关闭的玩笑,即使默认的 5 秒超时也是如此。
有什么提示吗?解决方法是模拟在我的逻辑中推送输出队列的函数,但我不喜欢它。
describe('foo', () => {
describe('bar', () => {
const fakeData = [{ id: 1 }]
const EE = new EventEmitter()
beforeAll(() => {
redisMock.new = jest.fn(() => ({
brpop: jest.fn(() => fakeData.pop()),
lpush: jest.fn((destQueue, data) => EE.emit('lpush', { destQueue, data })),
}))
mylogicWhichUsesRedis.start()
})
test('my test', (done) => {
EE.once('lpush', (params) => {
console.log(params)
expect(params.destQueue).toEqual('something')
console.log('test') // it will get till here
done()
})
})
})
})
PS 还添加了另一个测试版本,但仍然不起作用。这个版本的想法是尽量避免 did() 的上下文问题。
test('foobar', async () => {
const params = await new Promise((resolve) => {
EE.once('lpush', resolve)
})
expect(params.destQueue).toEqual('something')
console.log('this get printed')
})
我终于明白了这个问题:测试本身和设计都很好,没有什么问题,问题是
mylogicWhichUsesRedis.start()
有一种情况是它正在回忆自己(不是递归地),这出于某种原因让 Jest 发疯了。该函数不断调用直到无穷大,并且由于某种原因未触发 Jest 测试超时。
我添加了一个标志/信号量来从外部管理此行为并作为一个魅力。
test('my test', (done) => {
EE.once('lpush', (params) => {
mylogicWhichUsesRedis.mustStop = true // this block the eternal execution
expect(params.destQueue).toEqual('something')
done()
})
})