测试Django电子邮件后端

wro*_*ame 10 testing django unit-testing django-mailer

在我的settings.py中,我把:

EMAIL_BACKEND = 'mailer.backend.DbBackend'
Run Code Online (Sandbox Code Playgroud)

因此,即使从中导入from django.core.mail import send_mail,该send_mail函数仍会将数据库中的电子邮件排队,而不是立即发送.

它在实际运行网站时效果很好,但在测试网站和访问一些触发电子邮件的网页时,电子邮件不再排队了:

def test_something(self):
    ...
    # Check no emails are actually sent yet
    self.assertEquals(len(mail.outbox), 0) # test fails here -- 2 != 0

    # Check queued emails.
    messages = Message.objects.all()
    self.assertEquals(messages.count(), 2) # test would also fail here -- 0 != 2
    ...
Run Code Online (Sandbox Code Playgroud)

为什么它在测试时似乎没有使用后端?(send_mailmailer自身导入得到测试通过,但我不能真正改变其他邮件应用程序的导入,如django-templated-email)

Jac*_*ing 25

根据这个问题, django会setting.EMAIL_BACKEND在测试时覆盖'django.core.mail.backends.locmem.EmailBackend'.它也在这里的django文档中.

  • 得到了这个答案:http://stackoverflow.com/a/15053970/257583.非常感谢!! (4认同)

Ben*_*ath 5

要使用 django-mailer 正确测试电子邮件,您需要覆盖两个设置:

  1. 进行测试以使用 django-mailer 后端
  2. 使 djano-mailer 后端使用测试后端

如果您没有设置 django-mailer 后端(编号 2),您的测试将尝试发送真实的电子邮件。

您还需要模拟运行 django-mailer 的 send_mail 管理命令,以便您可以检查 mail.outbox 以获取正确的电子邮件。

以下是如何设置测试方法的示例:

from mailer.engine import send_all

@override_settings(EMAIL_BACKEND='mailer.backend.DbBackend')
@override_settings(MAILER_EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend')
def test_email(self):
    # Code that generates email goes here.

    send_all()  # Simulates running django-mailer's send_mail management command.

    # Code to check the email in mail.outbox goes here.
Run Code Online (Sandbox Code Playgroud)

这种策略使您的测试特定于您并不总是想要或需要的 django-mailer。我个人仅在测试 django-mailer 启用的特定功能时才使用此设置。否则,我使用 django 设置的默认测试电子邮件后端。