首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用sinon对nodejs“必需”构造函数进行存根?

如何使用sinon对nodejs“必需”构造函数进行存根?
EN

Stack Overflow用户
提问于 2015-12-24 19:39:05
回答 1查看 1.3K关注 0票数 1

我正在为一个使用email-templates模块的方法编写单元测试,如下所示:

代码语言:javascript
复制
var EmailTemplate = require('email-templates').EmailTemplate;

module.exports = {
    sendTemplateEmail: function (emailName, data, subject, to, from) {
        var template = new EmailTemplate(__dirname + "/../emails/" + emailName);

        data.from = FROM;
        data.host = config.host;

        return template.render(data)
            .then(function (result) {
                return mailer.sendEmail(subject, to, from, result.html, result.text);
            })
            .then(function () {
                log.info(util.format("Sent %s email to %s. data=%s", emailName, to, JSON.stringify(data)));
                return Promise.resolve();
            })
            .catch(function (err) {
                return Promise.reject(new InternalError(err, "Error sending %s email to %s. data=%s", emailName, to, JSON.stringify(data)));
            });
    }
};

单元测试如下所示:

代码语言:javascript
复制
var assert = require("assert"),
    sinon = require("sinon"),
    Promise = require("bluebird"),
    proxyquire = require("proxyquire");

describe('mailer#sendTemplateEmail', function () {
    var templates,
        template;

    beforeEach(function() {
        templates = {
            EmailTemplate: function(path) {}
        };
        template = {
            render: function(data) {}
        };

        sinon.stub(templates, "EmailTemplate").returns(template);
    });

    it("should reject immediately if template.render fails", function () {
        const TO = {email: "user1@example.com", first: "User"};
        const FROM = {email: "user2@example.com", first: "User"};
        const EMAIL_NAME = "results";
        const SUBJECT = "Results are in!";
        const DATA = {
            week: 10,
            season: "2015"
        };

        var err = new Error("error");
        var mailer = proxyquire("../src/mailer", {
            "email-templates": templates
        });

        sinon.stub(template, "render").returns(Promise.reject(err));

        return mailer.sendTemplateEmail(EMAIL_NAME, DATA, SUBJECT, TO, FROM)
                .then(function () {
                    assert.fail("Expected a rejected promise.");
                })
                .catch(function (err) {
                    assert(err.message === "error");
                    assert(mailer.sendEmail.notCalled);
                });
    });
};

我遇到的问题是在sendTemplateEmail函数的第一行,它实例化了一个新的EmailTemplate对象。被调用的EmailTemplate构造函数指向在beforeEach中定义的非存根EmailTemplate函数,而不是在beforeEach的最后一行上创建的sinon。但是,如果我计算require('email-templates').EmailTemplate语句,它将正确地指向sinon。我希望不必更改代码,以便内联地调用require语句,例如:

代码语言:javascript
复制
var template = new require('email-templates').EmailTemplate(__dirname + "/../emails/" + emailName);

有没有办法像我想的那样完成存根?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-24 19:53:51

在构造mailer时,可以注入依赖:

代码语言:javascript
复制
function mailer(options) {
  options = options || {};
  this.email_template = options.email_template;
}

然后在sendTemplateEmail函数中-使用email_template成员。

此外--不确定您的邮件程序代码--但是如果您需要您的邮件程序在您的代码中充当单例(而且它还不是),您可以将以下内容添加到您的邮件程序中:

代码语言:javascript
复制
module.exports = {
    getInstance: function(emailTemplate) {
        if(this.instance === null){
            this.instance = new mailer(emailTemplate);
        }
        return this.instance;
    }
}

然后,当您需要邮件程序时,可以使用以下语法:

代码语言:javascript
复制
var template = new require('email-templates').EmailTemplate(__dirname + "/../emails/" + emailName);
var mail = mailer.getInstance(template);

这样,您的应用程序(单元测试框架或实际/真实的应用程序)将确定将在流程生存期内使用的mailer类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34457232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档