2016-02-12 63 views
2

使用Django 1.7和Python 2.7。如何在Django中測試send_mail?

我想測試郵件是否被髮送以及郵件的內容是否正確。

我試過使用從django.core.mail發件箱,但無濟於事。 也可以只是得到stdout(因爲我可以在運行我的測試時看到控制檯中的郵件)?

models.py

class User(AbstractBaseUser, PermissionsMixin): 
    USERNAME_FIELD = 'email' 

    email = models.EmailField(max_length=255, unique=True) 
    is_staff = models.BooleanField(default=False) 
    org = models.ForeignKey('Org', null=True, blank=True, 
     on_delete=models.SET_NULL) 

    def __unicode__(self): 
     return self.email 

    @staticmethod 
    def send_password_token(email): 
     user = get_object_or_404(User, email=email) 
     token = Token.objects.get(user=user) 
     message_body = 'Your password reset token:\n\n\t%s' % token.key 
     send_mail('Password reset:', message_body, 
      settings.FROM_EMAIL, [email], fail_silently=False) 

tests.py

class UserModelTest(TestCase): 
    def setUp(self): 
     self.user = User.objects.create_user(email='[email protected]', 
      password='0000') 

    @override_settings(EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend') 
    def test_send_password_token(self): 
     """ 
     Sends a password reset mail with users authentication token. 
     """ 
     token = Token.objects.get(user=self.user) 
     User.send_password_token(self.user.email) 
+4

你見過[在docs示例](https://docs.djangoproject.com/en/1.9/topics/testing/tools/#email-services)?你應該刪除'override_settings'裝飾器。然後,Django將自動使用'locmem'電子郵件後端並將電子郵件放入發件箱供您檢查。 – Alasdair

+0

當您使用控制檯後端時,郵件只會被髮送到標準輸出,並且不能從django.core.mail郵箱使用。使用locmem後端。 https://docs.djangoproject.com/en/1.9/topics/email/#in-memory-backend –

回答

5

感謝@Alasdair的溶液。原來這很簡單。只需刪除override_settings並導入發件箱。

tests.py

from django.core.mail import outbox 

class UserModelTest(TestCase): 
    def setUp(self): 
     self.user = User.objects.create_user(email='[email protected]', 
      password='0000') 

    def test_send_password_token(self): 
     """ 
     Sends a password reset mail with users authentication token. 
     """ 
     token = Token.objects.get(user=self.user) 
     User.send_password_token(self.user.email) 
     self.assertEqual(len(outbox), 1) 
     self.assertEqual(outbox[0].subject, 'Password reset:') 
     self.assertEqual(outbox[0].from_email, <insert_from_email>) 
     self.assertEqual(outbox[0].to, [<insert_list_of_to_emails>]) 
     self.assertEqual(outbox[0].body, 
      'Your password reset token:\n\n\t%s' % token.key) 
+0

這可能在Django 2中已經改變 - 現在導入似乎是從'django.core導入郵件'和'發件箱被檢查像'mail.outbox' –