【发布时间】:2021-03-14 15:38:37
【问题描述】:
我正在测试一个异步方法,该方法使用 NodeJS 中的本机 https.request() 方法从 Web 请求中返回一些数据。我正在使用 mocha、chai 和 sinon 以及它们各自的相关扩展。
我正在测试的方法基本上将 NodeJS 文档中提供的样板 https.request() 代码包装在 Promise 中,并在收到响应“结束”事件时解析,或者如果收到请求“错误”事件则拒绝。与讨论相关的部分如下所示:
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();
});
}
如评论中所示,我要测试的是,如果发出请求错误事件,则错误会被正确记录。这就是我目前正在做的事情:
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);
});
这感觉像是一个 hack,但我不知道如何使用正常模式正确执行此操作。主要问题是我需要在调用方法之后但在履行承诺之前发出错误事件,如果我像通常使用 mocha 一样返回承诺,我看不到该怎么做。
【问题讨论】:
-
我看不出有什么问题。您可能还想在
request假冒中放入setTimeout(() => req.emit('error', err), demoDelay);,然后写await sut.fetch(…);,但任何一种方式都可以。 -
当你说“如果我像平常对待 mocha 那样返回承诺,我看不出该怎么做。”时你指的是什么?你的
async函数确实返回了一个对 mocha 的承诺。 -
@Bergi 你的 setTimeout 想法给了我想要的答案,谢谢!
标签: javascript node.js asynchronous mocha.js