9👍
Starting with version 3.2 Django has a build-in way to test the on_comit hook.
Example:
from django.core import mail
from django.test import TestCase
class ContactTests(TestCase):
def test_post(self):
with self.captureOnCommitCallbacks(execute=True) as callbacks:
response = self.client.post(
'/contact/',
{'message': 'I like your site'},
)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(callbacks), 1)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, 'Contact Form')
self.assertEqual(mail.outbox[0].body, 'I like your site')
Here is the official documentation: https://docs.djangoproject.com/en/stable/topics/testing/tools/#django.test.TestCase.captureOnCommitCallbacks
10👍
Just keep using TestCase and fake commit forcing executing of posponed actions in run_and_clear_commit_hooks.
Check this article:
https://medium.com/gitux/speed-up-django-transaction-hooks-tests-6de4a558ef96
1👍
Adam Johnson wrote this, and I think the code referenced here does the trick:
https://adamj.eu/tech/2020/05/20/the-fast-way-to-test-django-transaction-on-commit-callbacks/
@contextmanager
def captureOnCommitCallbacks(cls, *, using=DEFAULT_DB_ALIAS, execute=False):
"""Context manager to capture transaction.on_commit() callbacks."""
callbacks = []
start_count = len(connections[using].run_on_commit)
try:
yield callbacks
finally:
run_on_commit = connections[using].run_on_commit[start_count:]
callbacks[:] = [func for sids, func in run_on_commit]
if execute:
for callback in callbacks:
callback()
usage:
class ContactTests(TestCase):
def test_post(self):
with self.captureOnCommitCallbacks(execute=True) as callbacks:
response = self.client.post(
'/contact/',
{'message': 'I like your site'},
)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(callbacks), 1)
0👍
I have two possibilities in mind:
- as this section says
post_migrate
emitted after flush, so you can perform preloading some useful data - You can subclass
TransactionTestCase
and implement your_fixture_teardown
(you can see that flush is called there in the very end of method).
I’d probably stick with first one if your migration isn’t too expensive and with second one if it is.
- How can I make SSE with Python (Django)?
- Django + Forms: Dynamic choices for ChoiceField
- Subclassing Django ModelForms
- Django ListView customising queryset
- Django reverse error: NoReverseMatch