另一个函数中的mock django.core.mail.send_mail



我想模拟django的send_mail(),这样它就会抛出一个Exception。我的方法如下,但邮件仍在发送中,没有抛出异常。如果我直接在上下文管理器中调用send_mail(),但如果我调用一个导入然后使用send_mail()的函数,它就不会起作用

# test.py
import handle_alerts
from unittest import mock
class MailTest(TestCase):
def test_handle_alerts(self):
with mock.patch("django.core.mail.send_mail") as mocked_mail:
mocked_mail.side_effect = Exception("OH NOES")
handle_alerts()  # ends up using send_mail
# handle_alerts.py
from django.core.mail import send_mail
def handle_alerts():
send_mail(....)  # valid call goes here

您应该模拟函数的使用,而不是函数的声明。

class MailTest(TestCase):
def test_handle_alerts(self):
with mock.patch("handle_alerts.send_mail") as mocked_mail:
mocked_mail.side_effect = Exception("OH NOES")
handle_alerts()

如果有人像我一样为此而挣扎,你可能不需要嘲笑它(来源:Django测试电子邮件服务工具文档(:

Django的测试运行程序会自动将Django发送的所有电子邮件重定向到一个虚拟发件箱。这样,您就可以测试发送电子邮件的各个方面——从发送的邮件数量到每条邮件的内容——而无需实际发送邮件。

所以我们可以测试电子邮件是否是这样发送的:

self.assertEqual(len(mail.outbox), 1)

还测试邮件的其他方面(如主题、正文等(:

self.assertEqual(sended_mail.subject, "Your subject...")
self.assertEqual(sended_mail.recipients(), [your recipients])
self.assertEqual(sended_mail.from_email, your_from_email)

如果抛出异常,并且我们想要测试它,一个好的方法是设置数据以强制电子邮件抛出异常。如果它被抛出到实际的代码中,那么它将在测试中。然而,如果你只是想测试当电子邮件抛出一个嘲笑";包装器";函数发送电子邮件,@Ptomasz在Stack Overflow上提到了一个很好的方法:另一个函数中的mock django.core.mail.send_mail

最新更新