2

我正在为一个使用django-post_office包来实现其大部分电子邮件功能的应用程序编写测试。

默认django.core.mail库包含大量有用的工具,用于测试是否真的有电子邮件正在发送。(在测试期间没有实际发送任何内容)

class TestFunctionThatSendsEmail(Testcase):

   @override_settings(
        EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend'
   )
   def test_function_sends_email(self):
       self.assertEqual(len(outbox), 0)
       run_function_that_calls_email()
       self.assertEqual(len(outbox), 1)
       ...
       # other tests

但是,我们函数中的电子邮件是通过django-post_office mail.send()函数发送的

# priority now to make sure that they are being sent right away
mail.send(
        sender=sender,
        recipients=to,
        context=context,
        template=template_name,
        priority='now',
    )

这会导致上面的测试失败,因为由于某种原因,电子邮件不会最终出现在发件箱中。

奇怪的是,如果我将电子邮件更改为EMAIL_BACKEND确实django.core.mail.backends.console.EmailBackend显示在我的终端中,那么它正在监听EMAIL_BACKEND设置。

我尝试在django-post_officegithub 中寻找替代方法/功能来测试此功能,但我能找到的只是检查电子邮件是否保存到数据库并验证其状态的建议。(我做了并且工作)但是 django 似乎无法检测到任何实际发送的电子邮件的事实让我有点紧张。

有没有人知道一种方法可以使发送的电子邮件django-post_office出现在发件箱中,或者,如果不可能,一种方法来确保它们确实被发送?(除了检查数据库)

4

2 回答 2

1

我遇到了与您描述的相同的问题,并通过将其设置为DEFAULT_PRIORITY来修复它'now'

class TestFunctionThatSendsEmail(Testcase):

   @override_settings(
        POST_OFFICE={
            'BACKENDS': {'default': 'django.core.mail.backends.locmem.EmailBackend'},
            'DEFAULT_PRIORITY': 'now',
        }
   )
   def test_function_sends_email(self):
       self.assertEqual(len(outbox), 0)
       run_function_that_calls_email()
       self.assertEqual(len(outbox), 1)
       ...
       # other tests
于 2021-04-01T11:09:07.787 回答
1

问题是django-post_office将邮件后端存储在Email对象中:

class Email(models.Model):
    backend_alias = models.CharField(_("Backend alias"), blank=True, default='',
                                     max_length=64)

dispatch()被调用时,它使用这个后端。

创建电子邮件时,DPO 覆盖create()设置后端 from ,它在confdef get_available_backends()中查找后端。settings

这意味着 using@override_settings(EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend')不会正确设置对象backend_alias中的Email

相反,您需要在创建对象时手动执行此操作,根据调度测试:

def test_dispatch(self):
    """
    Ensure that email.dispatch() actually sends out the email
    """
    email = Email.objects.create(to=['to@example.com'], from_email='from@example.com',
                                 subject='Test dispatch', message='Message', backend_alias='locmem')
    email.dispatch()
    self.assertEqual(mail.outbox[0].subject, 'Test dispatch')

如果您正在使用mail.send(),您可以简单地将 themail.send(backend='locmem')作为参数传递;确保你有locmem': 'django.core.mail.backends.locmem.EmailBackend'你的POST_OFFICE设置

于 2020-07-16T11:42:15.533 回答