node.js模拟sendmailer传输器里面的函数
我在AWS lambda中使用节点处理程序,我需要使用该function进行集成testing的另一个文件,但我不能嘲笑与sinon或嘲笑的转运。
index.js函数:
var nodemailer = require('nodemailer'); exports.handler = (event, context, callback) => { var transporter=createTransporter(); transporter.sendMail(data, function (error, success) { console.log(error); response = getResponse(404, error); } callback(null, response); }); } function createTransporter() { return nodemailer.createTransport({ service: "SMTP", auth: { user: "XXXX@XXX", pass: "XXXX" } }); }
目的是嘲笑函数createTransporter(),以便它不发送任何电子邮件,当它在JavaScript文件testing与摩卡调用,并期望:
var mockery = require('mockery'); var nodemailerMock = require('nodemailer-mock'); var index = require("../index.js"); describe("The handler function tests", function () { before(function () { mockery.enable({ warnOnUnregistered: false }); mockery.registerMock('nodemailer', nodemailerMock); }); it('JSON error html ', function () { var callback = function (name, response) { expect(JSON.stringify(response.statusCode)).to.be('404'); }; var context = {}; index.handler(event, context, callback); }); });
我写了nodemailer-mock
🙂
你遇到的问题是你正在调用var index = require("../index.js");
在通过mockery
来嘲弄nodemailer
之前,它已经在模块caching中了。 我包括/ / // Make sure anything that uses nodemailer is loaded here, after it is mocked...
在自述文件中的例子,但应该更清楚。
在nodemailer
被nodemailer
之后移动require("../index.js")
,它将按预期工作。
var mockery = require('mockery'); var nodemailerMock = require('nodemailer-mock'); // don't require here since you will get the real nodemailer and cache it var index; describe("The handler function tests", function () { before(function () { mockery.enable({ warnOnUnregistered: false }); mockery.registerMock('nodemailer', nodemailerMock); // do the require() here after nodemailer is mocked index = require("../index.js"); }); // your tests here should now use nodemailer-mock it('JSON error html ', function () { var callback = function (name, response) { expect(JSON.stringify(response.statusCode)).to.be('404'); }; var context = {}; index.handler(event, context, callback); }); });
另一个select是使用{ useCleanCache: true }
选项来调用mockery.resetCache();
尽pipe我的结果好坏参半。 请参阅在嘲笑文档中控制模块caching 。
我不是100%肯定为什么这会失败,但我build议两件事之一:
- 尝试做
var createTransporter = function()
…这里有一个细微的差别,可能是你的问题 - 导出
createTransporter
这样你就可createTransporter
它分配一个新的值,不pipe是模拟的还是非模拟的。 这不是很“保持实现细节私密”,它确实有效 - 让你的模块返回一个类或者对象,在那里你可以设置一些“使用这个传输方法”的值。 (即dependency injection)