Django测试 - 发送电子邮件失败

时间:2012-11-21 19:26:53

标签: django testing

我在Django 1.4中有一个简单的功能,可以发送邮件。这是一个try / except,以防邮件服务可能已关闭(这是一个外部依赖)。

现在,我想测试这个异常。我认为通过覆盖一些电子邮件设置(如settings.EMAIL_HOST或settings.EMAIL_BACKEND)会很简单,但Django测试框架不会导致send_mail()抛出错误,即使后端配置为乱码...

所以问题是:如何让send_mail()在我的测试用例中抛出错误?

谢谢!


答案:

import mock
class MyTestCase(TestCase):
    @mock.patch('path.to.your.project.views.send_mail', mock.Mock(side_effect=Exception('Boom!')))
    def test_changed_send_mail(self):

4 个答案:

答案 0 :(得分:0)

是的,测试套件没有设置电子邮件系统。不幸的是,我不知道如何测试电子邮件系统。

你不应该真正测试send_mail函数,因为它是内置的。也就是说,你可以验证另一个函数传递给send_mail的数据。如果您知道预期输入的域,则可以验证并抛出(引发)您自己的异常。

答案 1 :(得分:0)

https://docs.djangoproject.com/en/1.4/topics/email/#the-emailmessage-class

这是发送电子邮件的更多django'y方式:

# attempt to send out a welcome email
try :
    t = loader.get_template('email_templates/membership/register.html')
    c = Context({
        'user'  : user,
        'site'  : Site.objects.get(id=settings.SITE_ID)
    })

    msg = EmailMessage('Welcome to Site', t.render(c), settings.EMAIL_HOST_USER, to=[user.email,])
    msg.content_subtype = "html"
    msg.send()
except :
    messages.info(request, _(u'Our email servers are encountering technical issues, you may not recieve a welcome email.'))

在我的settings.py中:

import os
EMAIL_HOST_USER = os.environ['SENDGRID_USERNAME']
EMAIL_HOST= 'smtp.sendgrid.net'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_PASSWORD = os.environ['SENDGRID_PASSWORD']

注意:SENDGRID_USERNAME和SENDGRID_PASSWORD由heroku插件添加为env变量,您可以在设置文件中嵌入实际凭据,这很好。

那么为什么你的电子邮件不会抛出异常? https://docs.djangoproject.com/en/1.4/topics/email/#django.core.mail.get_connection

  

fail_silently参数控制后端应该如何处理错误。如果fail_silently为True,则将默默忽略电子邮件发送过程中的异常。

答案 2 :(得分:0)

我不是测试专家,但我认为您应该使用send_mail模拟来引发您想要测试的异常。

您可以查看this stackoverflow question以了解更多有关Django中的嘲笑的信息。

答案 3 :(得分:0)

http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch上的补丁文档详细说明了如何解决此问题。

我注意到答案确实存在于问题中,但是为了帮助其他人理解捕获的位置,上面的链接将证明是非常有见地的。

如果要修补类b.py中的对象引用,请确保您的修补程序调用在b.py中而不是在导入对象的a.py中模拟对象引用。对于那些习惯于将功能视为一等公民的java开发人员来说,这可能是一个绊脚石。