Send-email testing with mail.outbox
See original GitHub issueI’ve written this simple test:
@when('asking for review and saving')
def act(self):
site = Site(domain='http://127.0.0.1:8000', name='127.0.0.1')
site.save()
request = {'SITE_ID': site.id}
self.asking_reservation = {'reservation_id': self.reservation1.id}
self.deserialized_data = AskForReviewSerializer(
data=self.asking_reservation, context={'request': request})
@then('validate data and send email for review asking')
def test(self):
with freeze_time(self.reservation_creation_date_plus_two_months):
assert self.deserialized_data.is_valid() == True
assert len(mail.outbox) == 0
self.deserialized_data.save()
assert len(mail.outbox) == 1
And this is the serializer I’m testing which sends an email when saving:
class AskForReviewSerializer(serializers.Serializer):
reservation_id = serializers.IntegerField()
def save(self, *args, **kwargs):
request = self.context.get('request')
current_site = get_current_site(request)
reservation_id = self.validated_data['reservation_id']
reservation = models.Reservation.objects.get(pk=reservation_id)
if not reservation.is_reviewable:
raise serializers.ValidationError('This reservation is not reviewable')
user = reservation.user
path = f'/reservations/{reservation_id}/review'
url = settings.BASE_URL + path
context = {'current_site': current_site,
'user': user,
'review_url': url,
'request': request}
get_adapter().send_mail(
'review/email/ask_for_review',
user.email,
context)
class Meta:
fields = ('reservation_id', )
But mail.outbox
is never affected when running the tests, its length is always zero (I ensured that my EMAIL_BACKEND = ‘django.core.mail.backends.locmem.EmailBackend’)
Full test: https://github.com/coretabs/dorm-portal/blob/master/features/steps/reviews.py#L117
Any idea how can I test the email sending behavior using behave-django?
Issue Analytics
- State:
- Created 5 years ago
- Comments:8 (4 by maintainers)
Top Results From Across the Web
testing send_email is not working - python - Stack Overflow
Outbox is special type attribute that can't import directly but when you send email using email backend then mail.outbox will work as list ......
Read more >Testing emails in Django | TimOnWeb
Email messages can and should be tested like any other piece of a web app. ... from django.core import mail print(len(mail.outbox)).
Read more >Outlook is not sending email - stuck in Outbox
To narrow the cause of the Outbox stuck emails, first of all you should check if you receive an error message while you...
Read more >Test Mail in Inbox but not in Outbox - WordPress.org
The test mail is send to the receiving mail address, so this is working. But I would like to see the mail in...
Read more >Configuration passes Test Message, but I still can't send e-mail
I believe my e-mail profile in Outlook is properly configured, ... wind up in the Outbox even though my settings succeed in passing...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
That is correct. That’s why you should use
context.test.client
if you want to access the DjangoTestCase
that is launched by behave-django. Then themail.outbox
behavior should match what is described in the Django docs you quote…I believe, there is a conceptual misunderstanding you’re trapped in. You should understand the way behave works (because behave-django is just marrying behave with Django), and how this affects writing tests for DRF, which you’re obviously using. Maybe you could take a look at similar issues (such as #46) and do some research on how writing tests with DRF in combination with behave. I just found out there is a dedicated project called behave-restful, maybe that makes your job easier? Not sure though.
I’m not exactly sure what would be the shortest way to helping you, but at first sight I see a few issues with your code:
context
. In your code this is alwaysself
. While this is not strictly a technical problem it may obscure the way to find a solution yourself. – Usecontext
as the first argument, the steps are functions not methods (see examples in the project repo).Site
. Can’t you use Django’s test client, which saves you from hard-coding URL values and such?mail
at the top of the module, I think that’s wrong. You should access the mail object that the Django test client has access to. It sounds obvious that otherwise the object is never populated.context.get_url(...)
.I like the way you call your step implementation functions (
act
,test
), though! 👍