对于单元测试(使用mocha),我想为事件设置某种异步队列。
到目前为止,我已经设置了一次()承诺等待事件:
import EventEmitter from 'events'
import { once } from 'events'
import { strict as assert } from 'assert'
describe('tests', function () {
const emitter = new EventEmitter()
it('testcase-1', async function () {
const ecmConfigurationPromise1 = once(emitter, 'event')
setTimeout(() => {
emitter.emit('event', { a: 1 })
})
assert.equal((await ecmConfigurationPromise1)[0].a, 1)
})
})
(setTimeout(...)
代表触发我的应用程序)
然而,现在我需要能够捕获具有相同名称的多个事件,并希望遵循等待它们的相同模式。我的想法是将事件存储在某个异步队列中(下面的XXX),但我找不到任何这样的东西。
import EventEmitter from 'events'
import { strict as assert } from 'assert'
describe('tests', function () {
const emitter = new EventEmitter()
it('testcase-2', async function () {
emitter.on('event', (msg) => XXX.push(msg))
setTimeout(() => {
emitter.emit('event', { a: 1 })
emitter.emit('event', { a: 2 })
})
assert.equal((await XXX)[0].a, 1)
assert.equal((await XXX)[0].a, 2)
// nice to have:
assert.equal(XXX.length(), 0)
})
})
有什么想法吗?
发布于 2021-05-25 21:27:12
似乎没有人有现成的解决方案,所以我将分享我自己的解决方案。
生成的测试用例相当简单:
it('testcase-2', async function () {
const eventPromise = waitForMultipleEvents('event', 3, (result, msg) => {
result.value += msg.a
})
setTimeout(() => { // simulate application under test
emitter.emit('event', { a: 1 })
emitter.emit('event', { a: 2 })
})
await eventPromise
})
这项工作在
const eventPromise = waitForMultipleEvents('event', 3, (result, msg) => {
result.value += msg.a
})
每个事件都会调用箭头函数,并执行一些特定于测试的分析,然后将结果存储在result.value中。当result.value等于提供的参数3
时,promise将满填,在超时的情况下,它将拒绝。
下面的样板让它发生了(输入脚本)
function sleep(ms: number) {
return new Promise(function (resolve) {
setTimeout(resolve, ms)
})
}
/**
* Helper function to wait for multiple occurences of same event. Needed
* because once() can only be used to catch a single shot of the same event.
*
* @param event bus event
* @param expect expected end value for result.value
* @param eventHandler function must be provided to analyze the received
* events. It should store its state in result.value
*
* @returns promise will resolve when result.value equals `expect` or reject
* on timeout.
*/
async function waitForMultipleEvents(
event: string,
expect: number,
eventHandler: (result: { value: number }, message: any) => void
): Promise<void> {
const result = { value: 0 }
emitter.on(event, (msg) => eventHandler(result, msg))
for (let i = 0; i < 20; i++) {
if (result.value == expect) {
break
}
await sleep(20)
}
await sleep(20) // Wait for additinal
emitter.removeAllListeners(event)
assert.equal(result.value, expect, `Too few/many ${event} received`)
}
https://stackoverflow.com/questions/67369494
复制相似问题