How to test emails send via EmailMessage .send() when email backend is set by EmailBackend object? As the backend is modified inside this function mail.outbox does not store any outgoing emails. What would be the most Django way of approaching this?
function in question:
def send_email_to_users(email_message_obj):
recipients = [user.email for user in email_message_obj.addressees.all()]
ap = Admin_Profile.objects.get(id=1)
backend = EmailBackend( host=ap.email_host,
port=ap.email_port,
username=ap.email_host_user,
password=ap.email_host_password,
use_tls=ap.email_use_tls,
fail_silently=False)
email = EmailMessage( subject=email_message_obj.title,
body=email_message_obj.body,
from_email=email_message_obj.email_from,
to=recipients,
connection=backend)
email.send()
test:
class Testsend_email_to_users(TestCase):
def setUp(self):
User.objects.create_superuser(
username='admin', email='jlennon@beatles.com', password='glassonion')
@override_settings(EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend')
def test_one_email(self):
'''should send one email'''
Admin_Profile.objects.create(
user=User.objects.all().first(),
email_host=settings.TEST_EMAIL_HOST,
email_port=settings.TEST_EMAIL_PORT,
email_host_user=settings.TEST_EMAIL_HOST_USER,
email_host_password=settings.TEST_EMAIL_HOST_PASSWORD,
email_use_tls=True,
)
u1 = mixer.blend(User, email=settings.ADMIN_EMAIL)
email_message = Email_Message.objects.create(
title='test title',
body='test body',
email_from=settings.TEST_EMAIL_HOST_USER,
)
email_message.addressees.add(u1)
send_email_to_users(email_message)
# should send one email
self.assertEqual(len(mail.outbox), 1)
result of the test:
> self.assertEqual(len(mail.outbox), 1)
E AssertionError: 0 != 1
models.py:
class Admin_Profile(models.Model):
...
email_host = models.CharField(max_length=100, blank=True)
email_port = models.IntegerField(null=True, blank=True)
email_host_user = models.EmailField(
max_length=70, null=True, blank=True)
email_host_password = models.CharField(max_length=100, blank=True)
email_use_tls = models.BooleanField(null=True, blank=True)
class Email_Message(models.Model):
title = models.CharField(max_length=78)
body = models.TextField()
email_from = models.EmailField()
addressees = models.ManyToManyField(settings.AUTH_USER_MODEL)
timestamp = models.DateTimeField(auto_now_add=True)
...
Notes:
send_email_to_usersis functional and sends 'real' emails;test_settings.py contains:
all other tests that use
django.core.mail.send_mailpass the tests and are captured in mail.outbox;additionally, test method was decorated with:
@override_settings(EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend'), but as the backend is specifically changed inside the function this has no impact;test_one_email sends 'real' email but fails on mail.outbox
Versions: Python 3.5.2, Django 2.2.9, pytest 4.0.2, pytest-django 3.4.4