用 mocha 测试异步函数 [英] Testing asynchronous function with mocha
问题描述
我想测试一个在 node.js 中运行的异步 javascript 函数并向 http api 发出简单请求:
I want to test a asynchronous javascript function that runs in node.js and makes a simple request to a http api:
const HOST = 'localhost';
const PORT = 80;
http = require('http');
var options = {
host: HOST,
port: PORT,
path: '/api/getUser/?userCookieId=26cf7a34c0b91335fbb701f35d118c4c32566bce',
method: 'GET'
};
doRequest(options, myCallback);
function doRequest(options, callback) {
var protocol = options.port == 443 ? https : http;
var req = protocol.request(options, function(res) {
var output = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
console.log(chunk);
output += chunk;
});
res.on('error', function(err) {
throw err;
});
res.on('end', function() {
var dataRes = JSON.parse(output);
if(res.statusCode != 200) {
throw new Error('error: ' + res.statusCode);
} else {
try {
callback(dataRes);
} catch(err) {
throw err;
}
}
});
});
req.on('error', function(err) {
throw err;
});
req.end();
}
function myCallback(dataRes) {
console.log(dataRes);
}
执行此代码有效,响应将按预期显示.
Executed this code works and the response will be displayed as expected.
如果我在 mocha 测试中执行此请求,则不会执行该请求:
If I execute this in a mocha test the request is not executed:
describe('api', function() {
it('should load a user', function() {
assert.doesNotThrow(function() {
doRequest(options, myCallback, function(err) {
if (err) throw err;
done();
});
});
assert.equal(res, '{Object ... }');
});
});
问题是,后面没有代码:
The Problem is, that no code after:
var req = protocol.request(options, function(res) {
甚至不是一个简单的 console.log.
is executed not even a simple console.log.
有人可以帮忙吗?
推荐答案
您必须指定回调 done
作为提供给 mocha 的函数的参数 - 在本例中为 it()
函数.像这样:
You have to specify the callback done
as the argument to the function which is provided to mocha - in this case the it()
function. Like so:
describe('api', function() {
it('should load a user', function(done) { // added "done" as parameter
assert.doesNotThrow(function() {
doRequest(options, function(res) {
assert.equal(res, '{Object ... }'); // will not fail assert.doesNotThrow
done(); // call "done()" the parameter
}, function(err) {
if (err) throw err; // will fail the assert.doesNotThrow
done(); // call "done()" the parameter
});
});
});
});
此外,doRequest(options, callback)
的签名指定了两个参数,但当您在测试中调用它时,您提供了三个参数.
Also, the signature of doRequest(options, callback)
specifies two arguments though when you call it in the test you provide three.
Mocha 可能找不到方法 doRequest(arg1,arg2,arg3)
.
Mocha probably couldn't find the method doRequest(arg1,arg2,arg3)
.
它没有提供一些错误输出吗?也许您可以更改 mocha 选项以获取更多信息.
Did it not provide some error output? Maybe you can change the mocha options to get more information.
andho 是对的,第二个断言将与 assert.doesNotThrow
并行调用,而它只应在成功回调中调用.
andho is right, the second assert would be called in parallel to assert.doesNotThrow
while it should only be called in the success callback.
我已经修复了示例代码.
I have fixed the example code.
编辑 2:
或者,为了简化错误处理(参见 Dan M. 的评论):
Or, to simplify the error handling (see Dan M.'s comment):
describe('api', function() {
it('should load a user', function(done) { // added "done" as parameter
assert.doesNotThrow(function() {
doRequest(options, function(res) {
assert.equal(res, '{Object ... }'); // will not fail assert.doesNotThrow
done(); // call "done()" the parameter
}, done);
});
});
});
这篇关于用 mocha 测试异步函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!