Testing asynchronous function with mocha

javascript, mocha.js, node.js, tdd, testing

Solution

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
            });
        });
    });
});

Also, the signature of `doRequest(options, callback)` specifies two arguments though when you call it in the test you provide three.

Mocha probably couldn't find the method `doRequest(arg1,arg2,arg3)`.

Did it not provide some error output? Maybe you can change the mocha options to get more information.

EDIT :

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.

EDIT 2:

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);
        });
    });
});

Problem

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. 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) { ``` is executed not even a simple console.log. Can anybody help?

Original source

Related problems