Mocha测试套件在尝试连接到API时出错

Mocha test suite errorring out when attempting to connect to API

本文关键字:API 出错 连接 测试 套件 Mocha      更新时间:2023-09-26

我正在通过gulp-jsx-coveragegulp-mocha使用mocha运行我的测试套件。我的所有测试都按预期运行并通过/失败。然而,我的一些正在测试的模块通过superagent库向我的API发出HTTP请求。

在开发过程中,我还在localhost:3000上运行我的API和我的客户端应用程序,因此这就是我的客户端测试试图访问的URL。然而,在测试时,API通常没有运行。每当请求通过时,都会导致以下错误:

Error in plugin 'gulp-mocha'
Message:
    connect ECONNREFUSED
Details:
    code: ECONNREFUSED
    errno: ECONNREFUSED
    syscall: connect
    domainEmitter: [object Object]
    domain: [object Object]
    domainThrown: false
Stack:
Error: connect ECONNREFUSED
    at exports._errnoException (util.js:746:11)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:983:19)

我已经尝试在全局助手中存根superagent(别名为request)库上的所有方法,如下所示:

function httpStub() {
  return {
    withCredentials: () => {
      return { end: () => {} };
    }
  };
};
beforeEach(function() {
  global.sandbox = sinon.sandbox.create();
  global.getStub = global.sandbox.stub(request, 'get', httpStub);
  global.putStub = global.sandbox.stub(request, 'put', httpStub);
  global.patchStub = global.sandbox.stub(request, 'patch', httpStub);
  global.postStub = global.sandbox.stub(request, 'post', httpStub);
  global.delStub = global.sandbox.stub(request, 'del', httpStub);
});
afterEach(function() {
  global.sandbox.restore();
});

但由于某种原因,当遇到一些测试时,方法没有被存根,因此我到达了ECONNREFUSED错误。我已经检查了三次,没有在哪里恢复沙箱或任何存根。

有没有办法解决我遇到的问题,或者有一个更清洁的整体解决方案?

问题可能是由于测试中没有正确执行异步操作而引起的。想象一下下面的例子:

it('is BAD asynchronous test', () => {
  do_something()
  do_something_else()
  return do_something_async(/* callback */ () => {
    problematic_call()
  })
})

当Mocha发现这样的测试时,它(同步)执行do_somethingdo_something_elsedo_something_async。在那一刻,从Mocha的角度来看,测试结束了,Mocha为它执行afterEach()(糟糕的是,problematic_call还没有调用!)和(更糟糕的是),它开始运行下一个测试!

现在,很明显,以并行的方式运行测试(以及beforeEach和afterEach)可能会导致非常奇怪和不可预测的结果,所以出现错误也就不足为奇了(可能是在某些测试的中间调用了Each,导致了环境的取消)

如何处理:

当你的测试结束时,总是向Mocha发出信号。这可以通过返回Promise对象来实现,也可以通过调用done回调:来实现

it('is BAD asynchronous test', (done) => {
  do_something()
  do_something_else()
  return do_something_async(/* callback */ () => {
    problematic_call()
    done()
  })
})

https://mochajs.org/

这样Mocha就可以"知道"你的测试何时结束,然后再进行下一次测试。

request已经是您的应用程序所必需的,所以您是否在测试中使用它并不重要。

您需要使用类似rewire的东西,并将应用程序所需的request替换为存根版本。

像这样的东西应该有助于

var request = require('superagent'),
    rewire = require('rewire'),
    sinon = require('sinon'),
    application = rewire('your-app'),
    rewiredRequest;
function httpStub() {
    return {
        withCredentials: () => {
            return { end: () => {} };
        }
    };
};
beforeEach(function() {
    var requestStub = {
        get: httpStub,
        put: httpStub,
        patch: httpStub,
        post: httpStub,
        del: httpStub
    };
    // rewiredRequest is a function that will revert the rewiring
    rewiredRequest = application.__set__({
        request: requestStub
    });
});
afterEach(function() {
  rewiredRequest();
});