我正在使用mocha
,gulp-jsx-coverage
和gulp-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
错误。我已经检查了三次,而且我没有在哪里恢复沙箱或任何存根。
是否有方法可以解决我遇到的问题,或者为此整体提供更清晰的解决方案?
答案 0 :(得分:4)
问题可能是由于在测试中没有正确执行异步操作引起的。想象一下以下示例:
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)可能会导致非常奇怪和不可预测的结果,所以出现错误并不奇怪(可能是在某些测试中调用了每个导致取消导致的调用之后)环境)
如何处理它:
当测试结束时,始终向Mocha发出信号。这可以通过返回Promise对象,或通过调用done
callback:
it('is BAD asynchronous test', (done) => {
do_something()
do_something_else()
return do_something_async(/* callback */ () => {
problematic_call()
done()
})
})
这样,Mocha'知道'你的测试何时结束,然后才开始下一次测试。
答案 1 :(得分:1)
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();
});