刚开始使用jest,文档在模拟方面似乎不太清楚。
我有一个带有以下代码的模块。如果我想测试发送邮件功能,但不通过mailgun发送实际的电子邮件,我需要在这做什么?我认为在我的测试文件中我需要使用模拟行为,但无法确定如何专门阻止邮件发出,同时还能够检查正确的路由,例如,无效的电子邮件地址,错误抛出等。我是否需要进一步打破此功能?
const Mailgun = require('machinepack-mailgun');
const Emailaddresses = require('machinepack-emailaddresses');
const config = require('../Config');
// Function to send an email
const sendEmail = function (toaddress, toname, sub, msg, cb) {
// Validate the email address is correct and if so send an email. Otherwise log the error and exit.
Emailaddresses.validate({
string: toaddress,
}).exec({
error(err) {
return cb(err, null);
},
invalid() {
return cb(new Error('Email address is not valid.'), null);
},
success() {
Mailgun.sendPlaintextEmail({
apiKey: config.sender.apiKey,
domain: config.sender.domain,
toEmail: toaddress,
toName: toname,
subject: sub,
message: msg,
fromEmail: config.sender.fromEmail,
fromName: config.sender.fromName,
}).exec({
error(err) {
return cb(err, null);
},
success() {
return cb(null, 'Email Sent.');
},
});
},
});
};
module.exports.sendEmail = sendEmail;
答案 0 :(得分:2)
您可以使用自己的实现模拟Mailgun
:
const Mailgun = require('machinepack-mailgun');
jest.mock('machinepack-mailgun', () = > ({
sendPlaintextEmail: jest.fn()
}))
it('sends mail and fail', () = > {
// no add the way `sendPlaintextEmail` should react.
// in this case return `exec` which always run the `error` part
Mailgun.sendPlaintextEmail.mockImplementation(() = > ({
exec: (arg) = > {
arg.error('someError')
}
}))
const cb = jest.fn()
sendEmail ('toaddress', 'toname', 'sub', 'msg', cb)
expect(Mailgun.sendPlaintextEmail).toHaveBeenCalledWith(...)
expect(cb).toHaveBeenCalledWith(...)
})
在上面的例子中,我们模拟了mailgun模块,以便sendPlaintextEmail
是间谍。然后我们将模块导入到我们的测试中,这样我们就可以在每个测试中设置spy的模拟实现。在示例中,我们设置了行为,以便它返回exec
方法,然后由您的代码使用error
/ success
对象调用该方法。然后模拟调用error
部分。之后,您可以首先使用正确的参数测试Mailgun.sendPlaintextEmail
,然后您可以使用cb
和"someError"
测试null
。
在另一项测试中,您只需设置exec
的行为,即可调用success
方法。