Django - 使用发件箱测试电子邮件 post_office
Django - testing emails with the outbox using post_office
我正在为使用 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_office
github 中寻找替代方法/函数来测试此功能,但我所能找到的只是检查电子邮件是否保存到数据库并验证其状态。 (我做了并且工作了)但是 django 似乎无法检测到任何实际发送的电子邮件这一事实让我有点紧张。
有谁知道让 django-post_office
发送的电子邮件出现在发件箱中的方法,或者,如果不可能的话,有什么方法可以确保它们确实被发送了吗? (除了检查数据库)
问题是 django-post_office
将邮件后端存储在 Email
对象中:
class Email(models.Model):
backend_alias = models.CharField(_("Backend alias"), blank=True, default='',
max_length=64)
当调用 dispatch()
时,它使用此后端。
创建电子邮件时,DPO 会覆盖 create()
以从 def get_available_backends()
设置后端,后者在 settings
conf.
中查找后端
这意味着使用 @override_settings(EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend')
不会正确设置 Email
对象中的 backend_alias
。
相反,您需要根据调度测试在创建对象时手动执行此操作:
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()
,您可以简单地将 mail.send(backend='locmem')
作为参数传递;确保 POST_OFFICE
设置中有 locmem': 'django.core.mail.backends.locmem.EmailBackend'
我遇到了与您描述的相同的问题,并通过将 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
我正在为使用 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_office
github 中寻找替代方法/函数来测试此功能,但我所能找到的只是检查电子邮件是否保存到数据库并验证其状态。 (我做了并且工作了)但是 django 似乎无法检测到任何实际发送的电子邮件这一事实让我有点紧张。
有谁知道让 django-post_office
发送的电子邮件出现在发件箱中的方法,或者,如果不可能的话,有什么方法可以确保它们确实被发送了吗? (除了检查数据库)
问题是 django-post_office
将邮件后端存储在 Email
对象中:
class Email(models.Model):
backend_alias = models.CharField(_("Backend alias"), blank=True, default='',
max_length=64)
当调用 dispatch()
时,它使用此后端。
创建电子邮件时,DPO 会覆盖 create()
以从 def get_available_backends()
设置后端,后者在 settings
conf.
这意味着使用 @override_settings(EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend')
不会正确设置 Email
对象中的 backend_alias
。
相反,您需要根据调度测试在创建对象时手动执行此操作:
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()
,您可以简单地将 mail.send(backend='locmem')
作为参数传递;确保 POST_OFFICE
设置中有 locmem': 'django.core.mail.backends.locmem.EmailBackend'
我遇到了与您描述的相同的问题,并通过将 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