I'm trying to test a Django model form that overrides the save method and implements a custom send_mail function. The send_mail function uses loader.render_to_string to generate an email body and then calls a custom send_email function to send the email. I'm having trouble writing the test case to properly assert the usage of these functions.
Here's my code:
class MockObjects:
def mock_render_to_string(self):
return 'This is an email'
class FormsTestCase(TestCase):
mock = MockObjects()
@patch('django.template.loader.render_to_string')
@patch('ext_libs.sendgrid.sengrid.send_email')
def test_send_mail(self, mock_send_email, mock_render_to_string):
form = CustomPasswordResetForm()
context = {'site_name': 'YourSiteName'}
to_email = 'testuser@example.com'
mock_render_to_string.return_value = self.mock.mock_render_to_string()
mock_send_email.return_value = None
form.send_mail(context, to_email)
mock_render_to_string.assert_called_once_with('registration/password_reset_email.html', context)
mock_send_email.assert_called_once_with(
destination=to_email,
subject="Password reset on YourSiteName",
content=mock_render_to_string.return_value
)
class CustomPasswordResetForm(PasswordResetForm):
def send_mail(self, context, to_email, *args, **kwargs):
print('got here')
email_template_name = 'registration/password_reset_email.html'
print('should call them')
body = loader.render_to_string(email_template_name, context)
print(f'got body {body}')
print('sending mail')
send_email(destination=to_email, subject=f"Password reset on {context['site_name']}", content=body)
print('sent')
#ext_libs.sendgrid.sengrid.send_email
def send_email(destination, subject, content, source=None, plain=False):
print('did it get here')
print(f'{destination}, {subject} {content}')
The issue I'm facing is that the test is failing with the following error:
AssertionError: Expected 'mock' to be called once. Called 0 times.
I traced the execution and the mocked classes are being called. Here is the full logs with prints
python .\manage.py test user.tests.test_forms.FormsTestCase.test_send_mail
{'default': {'ENGINE': 'django.db.backends.postgresql', 'NAME': 'feed_replica', 'USER': 'postgres', 'PASSWORD': 'P0stgres1.', 'HOST': 'localhost', 'PORT': '5432'}}
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
Running tests...
----------------------------------------------------------------------
got here
should call them
got body This is an email
sending mail
did it get here
testuser@example.com, Password reset on YourSiteName This is an email
end of method
sent
F
FAIL [5.601s]: test_send_mail (user.tests.test_forms.FormsTestCase.test_send_mail)
----------------------------------------------------------------------
Traceback (most recent call last):
File "Local\Programs\Python\Python311\Lib\unittest\mock.py", line 1369, in patched
return func(*newargs, **newkeywargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "test_forms.py", line 103, in test_send_mail
mock_send_email.assert_called()
File "Local\Programs\Python\Python311\Lib\unittest\mock.py", line 902, in assert_called
raise AssertionError(msg)
AssertionError: Expected 'send_email' to have been called.
Can anyone please show me why this issue is ocurring?