hyprstack
hyprstack

Reputation: 4228

sinon stubs not working in nodejs tests

I am writing the tests for the Invoicer module.

I am having two issues with my tests. The first one is that the emails are still being sent despite having stubbed the emailjs module (first test) and the second issue is that my second test timesout after 2secs.

I don't understand why?

Could anyone help me out with this?

Invoicer

'use strict';

var fs = require('fs');
var _ = require('underscore');
var request = require("request");
var email = require("emailjs");


exports.Invoicer = function (url, context) {

    // set-up our transporter object with credentials
    var transporter = email.server.connect({
        user: 'Pinoquio',
        password: 'sdlfkjlj',
        host: "[email protected]",
        port: 444,
        tls: true
    });

    // read html file for email
    fs.readFile('./email.html', function(error, data){

        if (error) {
            context.done(new Error("There was an error reading the file ---> %s", error.message));
        }

        data = data.toString();

        var template = _.template(data);

        // request data from url
        request(url, function (error, response, body) {
            if(error) {
                context.done(new Error("There was an error with request --> %s", error.message));
            }

            if (!error && response.statusCode == 200) {

                if(typeof body === "string") {
                    var _body = JSON.parse(body);
                }

                var populated_html = template(_body);

                var mailOptions = {
                    text: populated_html,
                    from: 'hick <[email protected]>', // sender address
                    to: '<[email protected]>', // recipient
                    subject: 'Invoice'
                }

                transporter.send(mailOptions, function(error, message){
                    if(error){
                        context.done(new Error("There was an error sending the email: %s", error.message));
                    }else{
                        context.done();
                    }
                });
            }
        });
    });
};

Tests

var chai = require('chai');
var sinonChai = require("sinon-chai");
var sinon = require('sinon');
chai.use(sinonChai);
var proxyquire = require('proxyquire');
var testedModule;
var fs = require('fs');
var email = require('emailjs').server.connect();
var expect = chai.expect;


describe('invoicer successful process', function () {

    var nock = require('nock');

    var ResponseOptions = {
        username: "Peter Pan",
        user_address_line_1: "Never Never Land",
        user_address_line_2: "Tree-house 99",
        user_post_code: "E4 9BY",
        delivery_address_line_1: "Hook's Boat",
        delivery_address_line_2: "Dock 69",
        delivery_post_code: "SE2 4C",
        order_number: "234234234",
        order_date: "20/12/2090",
        dispatch_date: "20/12/2090",
        items: [
            {
                product_name: "Fairy Dust",
                brand: "Airy fairy",
                quantity: 5,
                total: 2000
            },
            {
                product_name: "Pirate Sword",
                brand: "Pirate's Bay",
                quantity: 8,
                total: 2000
            }
        ],
        grand_total: 4000,
        user_email: "[email protected]"
    }

    var mailOptions = {
        text: "Hello World",
        from: 'hick <[email protected]>', // sender address
        to: '<[email protected]>', // recipient
        subject: 'Invoice'
    }

    var scope = nock("http://beta.hick.com")
        .get("/orders")
        .reply(200, ResponseOptions);

    var sendMailStub, readFileStub, url, contextDoneSpy, server;

    before(function () {

        server = sinon.fakeServer.create();
        server.autoRespond = true;

        sendMailStub = sinon.stub(email, "send");
        readFileStub = sinon.stub(fs, 'readFile');

        testedModule = proxyquire('../index.js', {
            fs: {readFile: readFileStub},
            email: {send: sendMailStub}
        });

        url = "http://beta.hick.com/orders";
        contextDoneSpy = sinon.spy();

        readFileStub.withArgs('./email.html').callsArgWith(1, null, 'file1');

        sendMailStub.withArgs(mailOptions).yields(null, contextDoneSpy);

    });

    after(function () {
        fs.readFile.restore();
        email.send.restore();
        server.restore();
    });

    it("readFile and successful context.done were called", function (done) {
        testedModule.Invoicer(url, { done: function () {
            contextDoneSpy.apply(null, arguments);
            expect(readFileStub).has.been.called;
            expect(contextDoneSpy).to.have.been.calledWithExactly();
            done();
        }});
    });
});

describe("fs.readFile", function () {

    var readFileStub, url, contextDoneSpy, server;

    before(function () {

        server = sinon.fakeServer.create();
        server.autoRespond = true;

        readFileStub = sinon.stub(fs, 'readFile');

        testedModule = proxyquire('../index.js', {
            fs: {readFile: readFileStub}
        });

        url = "http://beta.hick.com/orders";
        contextDoneSpy = sinon.spy();

        readFileStub.withArgs("Hello world").callsArgWith(1, new Error("Error reading file"), null);

    });

    after(function () {
        fs.readFile.restore();
        server.restore();
    });

    it("returns error", function (done) {
        testedModule.Invoicer(url, { done: function () {
            contextDoneSpy.apply(null, arguments);
            expect(contextDoneSpy).has.been.called.and.calledWith(new Error("Error reading file"));
            done();
        }});


    });
});

Upvotes: 1

Views: 967

Answers (1)

hyprstack
hyprstack

Reputation: 4228

I've managed to resolve the second issue first by placing return after the context.done(new Error....)

fs.readFile('./email.html', function(error, data){

if (error) {
    context.done(new Error("There was an error reading the file ---> %s", error.message));
    return;
}

and by passing in a valid file name in my test, as opposed to just a random string:

   readFileStub.withArgs("./email.html").callsArgWith(1, new Error("Error reading file"), null);
});

after(function () {
    fs.readFile.restore();
});

Upvotes: 1

Related Questions