im与AWS lambda中的节点处理程序一起工作,我需要使用该功能的集成测试进行另一个文件,但是我不能用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((,以便在使用Mocha中调用JavaScript文件测试时不会发送任何电子邮件,并期望:
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
:(
您遇到的问题是您在通过mockery
嘲笑nodemailer
之前正在调用var index = require("../index.js");
,因此它已经在模块缓存中了。我在读书中的示例中包括了 // Make sure anything that uses nodemailer is loaded here, after it is mocked...
,但可能应该使它更加清楚。
在模拟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);
});
});
另一个选项是将{ useCleanCache: true }
选项与mockery.resetCache();
调用一起使用,尽管我的结果好坏参半。请参阅嘲弄文档中的模块缓存。
我不是100%确定为什么会失败,但我建议两件事之一:
- 尝试做
var createTransporter = function()
...这里可能是您的问题 - 导出
createTransporter
,以便您可以为其分配一个新值,无论是否模拟。这不是"将实施细节保持私密",它确实有效 - 让您的模块返回 class ,或者无论如何,您可以在其中设置一些"使用此转运蛋白方法"值。(即依赖注射(
您可以使用Jest:
的以下选项jest.mock('nodemailer').setMock(/* function mock for module */)
请记住要在文件的顶部,导入或需要语句。这是官方的开玩笑文档:https://jestjs.io/docs/manual-mocks#mocking-node-modules。