I am building a mail backend that should add a specific address to the bcc of an email.
from django.conf import settings
from djcelery_email.backends import CeleryEmailBackend
class BCCEmailBackend(CeleryEmailBackend):
def send_messages(self, email_messages):
for i, message in enumerate(email_messages):
if settings.DEFAULT_BCC_EMAIL is not None:
message.bcc.append(settings.DEFAULT_BCC_EMAIL)
super().send_messages(email_messages)
When I run my test, the bcc is not set.
@override_settings(DEFAULT_BCC_EMAIL="[email protected]")
def test_default_bcc_email(self):
self.assertEqual(settings.DEFAULT_BCC_EMAIL, "[email protected]")
msg = EmailMultiAlternatives(
self.subject, self.text_content, "[email protected]", ["[email protected]"]
)
msg.attach_alternative(self.html_content, "text/html")
msg.send()
#...
# This test always fails
self.assertListEqual(m.bcc, ["[email protected]"], "Default bcc should be set")
When I set the bcc directly when initialising EmailMultiAlternatives my test is succeeding.
CodePudding user response:
This is documented behaviour as far as tests are concerned:
Django’s test runner automatically redirects all Django-sent email to a dummy outbox. This lets you test every aspect of sending email – from the number of messages sent to the contents of each message – without actually sending the messages.
The test runner accomplishes this by transparently replacing the normal email backend with a testing backend.
So, your custom backend is never used in your test, which is why it fails. I think the simplest way to address this is to write your test differently, to directly call the send_messages()
method on your class, e.g.:
msg = EmailMultiAlternatives(
self.subject, self.text_content, "[email protected]", ["[email protected]"])
# Note, you may have to mock out some behaviour of the backend to
# ensure it doesn't actually send an email.
BCCEmailBackend().send_messages([msg])
# This should pass now
self.assertListEqual(msg.bcc, ["[email protected]"], "Default bcc should be set")