测试Django电子邮件后端

时间:2013-04-24 08:16:40

标签: django unit-testing testing django-mailer

在我的settings.py中,我把:

EMAIL_BACKEND = 'mailer.backend.DbBackend'

因此,即使从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
    ...

为什么它在测试时似乎没有使用后端? (从send_mail本身导入mailer会让测试通过,但我无法真正更改其他邮件应用的导入,例如django-templated-email

4 个答案:

答案 0 :(得分:23)

根据此question django在测试setting.EMAIL_BACKEND时会覆盖'django.core.mail.backends.locmem.EmailBackend'。它也在django docs here中。

答案 1 :(得分:3)

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

  1. 进行测试以使用django-mailer后端
  2. 让djano-mailer后端使用测试后端
  3. 如果您没有设置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.
    

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

答案 2 :(得分:0)

如果您真的想在django测试中通过SMTP发送电子邮件(如默认),请使用装饰器:

from django.test.utils import override_settings    
@override_settings(EMAIL_BACKEND='django.core.mail.backends.smtp.EmailBackend')
class TestEmailVerification(TestCase):
   ...

答案 3 :(得分:0)

尝试以下操作:

django.core.mail.backends.console.EmailBackend