nodejs:如何为单元测试存储多个同名事件

如何解决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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?