【问题标题】:Django testing - fail on sending emailDjango 测试 - 发送电子邮件失败
【发布时间】:2012-11-10 03:20:57
【问题描述】:

我在 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):

【问题讨论】:

    标签: django testing


    【解决方案1】:

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

    也许你可以看看this stackoverflow question 以了解更多关于在 Django 中模拟的信息。

    【讨论】:

    • 所以基本上只是模拟 send_mail() 以返回错误...需要尝试一下!
    • 所以似乎模拟一个函数比我希望的要困难......大多数文档都在谈论模拟一个类对象及其方法。
    • 看起来简单的答案是最优雅的。在问题中回答!
    【解决方案2】:

    是的,测试套件不设置电子邮件系统。不幸的是,我不知道有什么方法可以测试电子邮件系统。

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

    【讨论】:

    • 同意 send_mail 功能不由我测试。话虽如此,我的部分代码依赖 send_mail 来引发异常。而我想测试的那部分代码......
    【解决方案3】:

    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 插件添加为环境变量的,您可能会将实际凭据嵌入到您的设置文件中,这很好。

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

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

    【讨论】:

    • 嗨!谢谢你的例子,真的很有帮助!假设他们在改进我的代码方面很有启发性......话虽如此,我仍然存在无法在我的测试用例中引发异常的问题。当我将设置更改为 gibber (知道它不会发送电子邮件)并手动测试时,它会引发异常。我从 manage.py 运行测试,即使乱码设置仍然存在,并且测试通过了...
    • 你的 DEBUG 设置是什么?
    【解决方案4】:

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

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

    如果您想修补类 b.py 中的对象引用,请确保您的修补程序调用模拟 b.py 中的对象引用,而不是从导入对象的 a.py 中模拟对象引用。对于习惯于将函数作为一等公民的整个想法的 Java 开发人员来说,这可能是一个绊脚石。

    【讨论】:

      猜你喜欢
      • 2022-08-20
      • 1970-01-01
      • 2017-12-08
      • 1970-01-01
      • 1970-01-01
      • 2017-02-09
      • 1970-01-01
      • 2016-07-26
      • 1970-01-01
      相关资源
      最近更新 更多