Search code examples
javascriptnode.jsmocha.jses6-promisesinon

nodejs mocha - not able to test promises with stubs


I am trying to unit test promises with mocha, however, I am having two issues while testing promises.

1) I am having Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

2) my requestStub behavior is not restored or cleared after 1st test which means 2nd test is still depending on first behavior.

handler.js

"use strict";

var request = require('request');

class Handler {
    constructor() {};

    getMarketData(symbol) {
        return new Promise(function(resolve, reject) {
            request("https://api.binance.com/api/v1/klines?symbol=" + symbol + "BTC&interval=1h", 
                function(err, res, body) {
                    if (err) {
                        return reject(err);
                    }
                    return resolve(JSON.parse(body));
            });
        });
    }
}

module.exports = Handler;

handler-test.js

"use strict";

var assert = require('assert');
var sinon = require('sinon');
var proxyquire = require('proxyquire').noCallThru();

describe("Handler", function() {
    var handlerInstance;
    var requestStub;

    before(function() {
        requestStub = sinon.stub();
        var Handler = proxyquire("./handler.js", {"request": requestStub});
        handlerInstance = new Handler();
    });

    afterEach(function() {
        requestStub.restore;
    });

    describe("#getMarketData", function() {
        it("test 1", function() {
            var promise = handlerInstance.getMarketData("VTC");
            requestStub.withArgs(sinon.match.any, sinon.match.any).yields(null, null, JSON.stringify({symbol: "VTC"}));
            return promise.then(function(data) {
                assert.equals(data.symbol, "VTC");
            });
        });

        it("test 2", function() {
            var promise = handlerInstance.getMarketData("STRAT");
            requestStub.withArgs(sinon.match.any, sinon.match.any).yields(null, null, JSON.stringify({symbol: "STRAT"}));
            return promise.then(function(data) {
                assert.equal(data.symbol, "STRAT");
            });
        });
    });
});

Solution

  • You need to set the behaviour of requestStub before you call getMarketData().

    At the moment when you call request() inside getMarketData() it doesn't have anything to do. So your callback never gets called, and the test timesout.