如何测试从 node.js http 请求生成的事件?

How to test events generated from node.js http request?

我有一个 node.js 代码,我正在使用 mocha 和 sinon 进行测试

var request = require('request');
request.get(url, function (error, response, body) {
  /* code I already tested */
})
.on('error', function(err) {
  /* code I want to test */
})

我用 sinon var requestGet = sinon.stub(request, 'get'); 创建了一个存根,我创建了不同的单元来测试 /* code I already tested */

现在我想测试 /* code I want to test */request.get() 发出 error 事件时执行的代码,但我不知道该怎么做。

您只需要创建自己的 EventEmitter,存根 .get 方法并根据需要使用它。您将能够发出任何事件:

//Stubbing
emitter = new EventEmitter();
sandbox.stub(request, 'get').returns(emitter);

//And when you need to fire the event:
emitter.emit('error', new Error('critical error'));

这是一个例子。

假设你有一个方法 makeRequest。并且您想测试在出现严重错误的情况下必须通过调用 application.stop().

来停止应用程序

您可以通过以下方式对其进行测试(请参阅我的评论):

const request = require('request');
const sinon = require('sinon');
const assert = require('assert');
const { EventEmitter } = require('events');

const application = { stop () { console.log('appliation is stopped') } };

const makeRequest = () => {
    return request
        .get('http://google.com', function (error, response, body) {
            if (error) { return console.error(error); }

            console.log('executed');
        })
        .on('error', err => {
            if (err.message === 'critical error') {
                application.stop();
            }
        });
}

describe('makeRequest', () => {
    let emitter;

    let sandbox = sinon.createSandbox();
    let stopSpy;

    beforeEach(() => {
        // Using our own emitter. We'll be able to raise any events.
        emitter = new EventEmitter();

        // We don't want the standard `get` logic to be executed as we are testing the error only.
        // Notice - we are returning `emitter` so the .on method exists.
        sandbox.stub(request, 'get').returns(emitter);

        stopSpy = sandbox.spy(application, 'stop');
    });


    it('should stop the app in case of a critical error', () => {
        // No need to worry about the callbacks, the stubbed method is sync.
        makeRequest();

        // Now emitting the error.
        emitter.emit('error', new Error('critical error'));

        // Checking if the required method has been called.
        assert.equal(stopSpy.calledOnce, true);
    });

    afterEach(() => sandbox.restore());
})