Mocha 测试套件在尝试连接到 API 时出错
Mocha test suite errorring out when attempting to connect to API
我正在 运行使用 mocha
,通过 gulp-jsx-coverage
和 gulp-mocha
设置我的测试套件。我所有的测试 运行 和 pass/fail 都符合预期。但是,我的一些正在测试的模块通过 superagent
库向我的 API 发出 HTTP 请求。
在开发过程中,我还在 localhost:3000
与我的客户端应用程序 运行 连接我的 API,这就是 URL 我的客户端-端测试正在尝试访问。但是,在测试时,API 通常不是 运行ning。每当请求通过时,这都会导致以下错误:
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_something
、do_something_else
和 do_something_async
。在那一刻,从 Mochas 的角度来看,测试结束了,Mocha 为它执行了 afterEach() (糟糕的是, problematic_call
仍然没有被调用!)并且(更糟糕的是),它开始 运行下一个测试!
现在,很明显,运行 并行测试(以及 beforeEach 和 afterEach)会导致非常奇怪和不可预测的结果,所以出现错误也就不足为奇了(可能是在一些导致 unstubbing 环境的测试)
如何处理:
总是在测试结束时向 Mocha 发出信号。这可以通过返回 Promise 对象或调用 done
回调来完成:
it('is BAD asynchronous test', (done) => {
do_something()
do_something_else()
return do_something_async(/* callback */ () => {
problematic_call()
done()
})
})
这样 Mocha 'knows' 当你的测试结束时它才运行下一个测试。
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();
});
我正在 运行使用 mocha
,通过 gulp-jsx-coverage
和 gulp-mocha
设置我的测试套件。我所有的测试 运行 和 pass/fail 都符合预期。但是,我的一些正在测试的模块通过 superagent
库向我的 API 发出 HTTP 请求。
在开发过程中,我还在 localhost:3000
与我的客户端应用程序 运行 连接我的 API,这就是 URL 我的客户端-端测试正在尝试访问。但是,在测试时,API 通常不是 运行ning。每当请求通过时,这都会导致以下错误:
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_something
、do_something_else
和 do_something_async
。在那一刻,从 Mochas 的角度来看,测试结束了,Mocha 为它执行了 afterEach() (糟糕的是, problematic_call
仍然没有被调用!)并且(更糟糕的是),它开始 运行下一个测试!
现在,很明显,运行 并行测试(以及 beforeEach 和 afterEach)会导致非常奇怪和不可预测的结果,所以出现错误也就不足为奇了(可能是在一些导致 unstubbing 环境的测试)
如何处理:
总是在测试结束时向 Mocha 发出信号。这可以通过返回 Promise 对象或调用 done
回调来完成:
it('is BAD asynchronous test', (done) => {
do_something()
do_something_else()
return do_something_async(/* callback */ () => {
problematic_call()
done()
})
})
这样 Mocha 'knows' 当你的测试结束时它才运行下一个测试。
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();
});