sinon存根不在nodejs测试中工作

时间:2015-04-28 13:20:07

标签: node.js unit-testing sinon

我正在编写Invoicer模块的测试。

我的测试有两个问题。第一个问题是尽管已经发送了emailjs模块(第一次测试),但仍然发送了电子邮件,第二个问题是我的第二次测试超过了2秒后的超时。

我不明白为什么?

有人可以帮我解决这个问题吗?

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: "pinoquio@gmail.com",
        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 <hick@beta.hick.com>', // sender address
                    to: '<mario@hick.com>', // 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: "peter@flyaway.com"
    }

    var mailOptions = {
        text: "Hello World",
        from: 'hick <hick@beta.hick.com>', // sender address
        to: '<mario@hick.com>', // 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();
        }});


    });
});

1 个答案:

答案 0 :(得分:1)

我已设法通过return

之后放置context.done(new Error....)来解决第二个问题

fs.readFile(&#39; ./ email.html&#39;,功能(错误,数据){

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

并在我的测试中传入一个有效的文件名,而不是只是一个随机字符串:

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

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