简体   繁体   English

如何使用 mocha/sinon/chai 正确测试异步 stream 错误事件处理?

[英]How do I correctly test asynchronous stream error event handling with mocha/sinon/chai?

I am testing an async method that returns some data from a web request using the native https.request() method in NodeJS.我正在测试一个异步方法,该方法使用 NodeJS 中的本机 https.request() 方法从 web 请求中返回一些数据。 I am using mocha, chai, and sinon with the relevant extensions for each.我正在使用 mocha、chai 和 sinon 以及它们的相关扩展。

The method I'm testing essentially wraps the boilerplate https.request() code provided in the NodeJS docs in a Promise and resolves when the response 'end' event is received or rejects if the request 'error' event is received.我正在测试的方法基本上包装了 Promise 中 NodeJS 文档中提供的样板 https.request() 代码,并在收到响应“结束”事件时解析,或者在收到请求“错误”事件时解决。 The bits relevant to discussion look like this:与讨论相关的部分如下所示:

async fetch(...) {
    // setup

    return new Promise((resolve, reject) => {
        const req = https.request(url, opts, (res) => {
            // handle response events
        });
        
        req.on('error', (e) => {
            logger.error(e);  // <-- this is what i want to verify
            reject(e);
        });

        req.end();
    });
}

As indicated in the comment, what I want to test is that if the request error event is emitted, the error gets logged correctly.如评论中所示,我要测试的是,如果发出请求错误事件,则错误会被正确记录。 This is what I'm currently doing to achieve this:这就是我目前正在做的事情:

it('should log request error events', async () => {
    const sut = new MyService();
    const err = new Error('boom');
    const req = new EventEmitter();
    req.end = sinon.fake();
    const res = new EventEmitter();
    sinon.stub(logger, 'error');
    sinon.stub(https, 'request').callsFake((url, opt, cb) => {
        cb(res);
        return req;
    });

    try {
        const response = sut.fetch(...);
        req.emit('error', err);
        await response;
    } catch() {}

    logger.error.should.have.been.calledOnceWith(err);
});

This feels like a hack, but I can't figure out how to do this correctly using the normal patterns.这感觉就像一个黑客,但我无法弄清楚如何使用正常模式正确地做到这一点。 The main problem is I need to emit the error event after the method is called but before the promise is fulfilled, and I can't see how to do that if I am returning the promise as you normally would with mocha.主要问题是我需要在调用方法之后但在 promise 完成之前发出错误事件,如果我像通常使用摩卡咖啡一样返回 promise,我看不到该怎么做。

I should have thought of this, but @Bergi's comment about using setTimeout() in the fake gave me an idea and I now have this working with the preferred syntax:我应该想到这一点,但@Bergi 关于在假中使用 setTimeout() 的评论给了我一个想法,我现在可以使用首选语法:

it('should log request error events', () => {
    const sut = new MyService();
    const err = new Error('boom');
    const req = new EventEmitter();
    req.end = sinon.fake();
    const res = new EventEmitter();
    sinon.stub(logger, 'error');
    sinon.stub(https, 'request').callsFake((url, opt, cb) => {
        cb(res);
        setTimeout(() => { req.emit('error', err); });
        return req;
    });

    return sut.fetch(...).should.eventually.be.rejectedWith(err)
        .then(() => {
            logger.error.should.have.been.calledOnceWith(err);
        });
});

I don't like adding any delays in unit tests unless I'm specifically testing delayed functionality, so I used setTimeout() with 0 delay just to push the emit call to the end of the message queue.除非我专门测试延迟功能,否则我不喜欢在单元测试中添加任何延迟,因此我使用了延迟为 0 的 setTimeout() 来将发出调用推送到消息队列的末尾。 By moving it to the fake I was able to just use promise chaining to test the call to the logger method.通过将它移动到假的,我能够使用 promise 链接来测试对记录器方法的调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 模拟和测试Mocha,Chai和Sinon的按键事件? - Simulate and test a keypress event with Mocha, Chai, Sinon? 如果变量具有反应组件作为值,我如何使用 mocha/chai/sinon 进行单元测试? - How do i unit test using mocha/chai/sinon if a variable has a react component as value? 如何测试使用Mocha,Sinn和Chai返回的函数? - How do I test a function which returns a function using Mocha, Sinon, and Chai? 如何使用 mocha、chai 和 sinon 模拟和测试闭包 - How to mock, and test, closures with mocha, chai and sinon 如何检查Mocha Chai Sinon是否存在元素? - How do I check if element exists with Mocha Chai Sinon? 为浏览器调整大小事件编写测试。 PhantomJS,摩卡,柴和诗乃 - Writing a test for a browser resize event. PhantomJS, Mocha, Chai & Sinon 如何在异步函数中包装Mocha / Chai测试? - How do I wrap Mocha/Chai tests within asynchronous functions? 如何使用Mocha,Chai和Sinon正确测试Express控制器方法 - How to properly test an Express controller method with Mocha, Chai, and Sinon 如何使用vanillajs和nodejs在Mocha / Chai / Sinon中测试addEventListener? - How to test addEventListener in Mocha/Chai/Sinon with vanillajs and nodejs? 如何测试Mocha / Chai以验证是否为变量分配了值? - How do I test Mocha/Chai to verify that a variable was assigned a value?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM