我想在我的代码中测试一个执行一组不同函数的方法......并在调用时调用其中一个内部函数,发送一封电子邮件。
我想要的是避免此功能在运行测试时发送电子邮件。有没有办法实现这个目标?
我想在我的代码中逃避以下内容:
if (app.get('env') !== 'test')
我使用 Promises ,我想测试的功能如下:
var emailService = require('../path/to/custom/service.js');
// This is the method I want to test
exports.sendKeyByEmail = function(email) {
return _getByEmail(email) // finds a user given an email
.then(function(user) {
if (!user) {
throw new UserNotFoundError();
}
user.key = _generateKey(); // generates a random hash
return user.save(); // saves the user (mongoose stuff...)
})
.then(function(user) {
// This is what I would like to mock during testing
return emailService.sendKey(user.email, user.key);
});
}
emailService.sendKey()
方法是发送电子邮件并返回Promise的方法。在测试期间,我希望它直接返回一个已完成的Promise Promise.resolve()
,而不是真正发送电子邮件。
答案 0 :(得分:1)
I answered a question just like this yesterday:不是将两个关注点合并到私有方法或隐藏函数中,而是将它们分成两个类,并将电子邮件实现传递给外部类。这将允许您在测试期间提供模拟emailService
并且非常巧妙地解决您的问题。
当设置它时,我是构造函数依赖注入的粉丝,因为它为你提供了DI的好处而没有做任何棘手的事情(比如反射)。使用ES6参数,您还可以在不嘲笑任何内容时提供默认值。
非常粗略地说,你可以这样做:
var defaultEmailService = require('../path/to/custom/service.js');
// This is the method I want to test
exports.sendKeyByEmail = function(email, emailService = defaultEmailService) {
return _getByEmail(email) // finds a user given an email
.then(function(user) {
if (!user) {
throw new UserNotFoundError();
}
user.key = _generateKey(); // generates a random hash
return user.save(); // saves the user (mongoose stuff...)
})
.then(function(user) {
// This is what I would like to mock during testing
return emailService.sendKey(user.email, user.key);
});
}
在您的测试中,只需传递一个模拟emailService
,它可以在不触及网络的情况下返回可预测的结果。