有 MockFunction 吗?
Jest Mock Function?
刚开始使用 jest,文档对 mocking 似乎不是很清楚。
我有一个包含以下代码的模块。如果我想测试发送邮件功能,而不是通过 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;
您可以使用自己的实现来模拟 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
是一个间谍。然后我们将模块导入到我们的测试中,这样我们就可以在每个测试中设置间谍的模拟实现。在示例中,我们设置了行为,因此它 returns exec
方法,然后您的代码使用 error
/success
对象调用该方法。然后模拟只调用 error
部分。之后,您可以先测试 Mailgun.sendPlaintextEmail
是否使用正确的参数调用,然后您可以测试 cb
是否使用 "someError"
和 null
.
调用
在另一个测试中,您只需设置 exec
的行为,这样它就会调用 success
方法。
刚开始使用 jest,文档对 mocking 似乎不是很清楚。
我有一个包含以下代码的模块。如果我想测试发送邮件功能,而不是通过 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;
您可以使用自己的实现来模拟 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
是一个间谍。然后我们将模块导入到我们的测试中,这样我们就可以在每个测试中设置间谍的模拟实现。在示例中,我们设置了行为,因此它 returns exec
方法,然后您的代码使用 error
/success
对象调用该方法。然后模拟只调用 error
部分。之后,您可以先测试 Mailgun.sendPlaintextEmail
是否使用正确的参数调用,然后您可以测试 cb
是否使用 "someError"
和 null
.
在另一个测试中,您只需设置 exec
的行为,这样它就会调用 success
方法。