如何解决nodejs:如何为单元测试存储多个同名事件
对于单元测试(使用 mocha),我想为事件设置某种异步队列。
到目前为止,我已经设置了一个 once() Promise 来等待事件:
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)
})
})
有什么想法吗?
解决方法
似乎没有人有现成的解决方案,所以我将分享我自己的解决方案。
生成的测试用例相当简单:
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',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`)
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。