使用mocha测试异步函数

Mad*_*ool 30 javascript testing tdd mocha.js node.js

我想测试一个在node.js中运行的异步javascript函数,并向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);
}
Run Code Online (Sandbox Code Playgroud)

执行此代码有效,响应将按预期显示.

如果我在mocha测试中执行此操作,则不执行请求:

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 ... }');
    });
});
Run Code Online (Sandbox Code Playgroud)

问题是,之后没有代码:

var req = protocol.request(options, function(res) {
Run Code Online (Sandbox Code Playgroud)

甚至没有一个简单的console.log执行.

有人可以帮忙吗?

Ris*_*nha 46

您必须将回调指定done为提供给mocha的函数的参数 - 在本例中为it()函数.像这样:

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
            });
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

此外,签名doRequest(options, callback)指定两个参数,但是当您在提供三个参数的测试中调用它时.

摩卡可能找不到方法doRequest(arg1,arg2,arg3).

它没有提供一些错误输出吗?也许您可以更改mocha选项以获取更多信息.

编辑:

andho是对的,第二个断言将被并行调用,assert.doesNotThrow而它应该只在成功回调中被调用.

我修复了示例代码.

编辑2:

或者,为了简化错误处理(参见Dan M.的评论):

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);
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

  • 在你的例子中,不会`assert.equal(res,'{Object ...}');`在调用之前调用? (4认同)