mirror of
https://github.com/django/django.git
synced 2025-10-24 14:16:09 +00:00
Fixed #30457 -- Added TestCase.captureOnCommitCallbacks().
This commit is contained in:
committed by
Mariusz Felisiak
parent
ca6c5e5fc2
commit
e906ff6fca
@@ -276,6 +276,11 @@ Tests
|
||||
* :class:`~django.test.Client` now preserves the request query string when
|
||||
following 307 and 308 redirects.
|
||||
|
||||
* The new :meth:`.TestCase.captureOnCommitCallbacks` method captures callback
|
||||
functions passed to :func:`transaction.on_commit()
|
||||
<django.db.transaction.on_commit>` in a list. This allows you to test such
|
||||
callbacks without using the slower :class:`.TransactionTestCase`.
|
||||
|
||||
URLs
|
||||
~~~~
|
||||
|
||||
|
||||
@@ -394,9 +394,19 @@ Use in tests
|
||||
Django's :class:`~django.test.TestCase` class wraps each test in a transaction
|
||||
and rolls back that transaction after each test, in order to provide test
|
||||
isolation. This means that no transaction is ever actually committed, thus your
|
||||
:func:`on_commit` callbacks will never be run. If you need to test the results
|
||||
of an :func:`on_commit` callback, use a
|
||||
:class:`~django.test.TransactionTestCase` instead.
|
||||
:func:`on_commit` callbacks will never be run.
|
||||
|
||||
You can overcome this limitation by using
|
||||
:meth:`.TestCase.captureOnCommitCallbacks`. This captures your
|
||||
:func:`on_commit` callbacks in a list, allowing you to make assertions on them,
|
||||
or emulate the transaction committing by calling them.
|
||||
|
||||
Another way to overcome the limitation is to use
|
||||
:class:`~django.test.TransactionTestCase` instead of
|
||||
:class:`~django.test.TestCase`. This will mean your transactions are committed,
|
||||
and the callbacks will run. However
|
||||
:class:`~django.test.TransactionTestCase` flushes the database between tests,
|
||||
which is significantly slower than :class:`~django.test.TestCase`\'s isolation.
|
||||
|
||||
Why no rollback hook?
|
||||
---------------------
|
||||
|
||||
@@ -881,6 +881,42 @@ It also provides an additional method:
|
||||
previous versions of Django these objects were reused and changes made
|
||||
to them were persisted between test methods.
|
||||
|
||||
.. classmethod:: TestCase.captureOnCommitCallbacks(using=DEFAULT_DB_ALIAS, execute=False)
|
||||
|
||||
.. versionadded:: 3.2
|
||||
|
||||
Returns a context manager that captures :func:`transaction.on_commit()
|
||||
<django.db.transaction.on_commit>` callbacks for the given database
|
||||
connection. It returns a list that contains, on exit of the context, the
|
||||
captured callback functions. From this list you can make assertions on the
|
||||
callbacks or call them to invoke their side effects, emulating a commit.
|
||||
|
||||
``using`` is the alias of the database connection to capture callbacks for.
|
||||
|
||||
If ``execute`` is ``True``, all the callbacks will be called as the context
|
||||
manager exits, if no exception occurred. This emulates a commit after the
|
||||
wrapped block of code.
|
||||
|
||||
For 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')
|
||||
|
||||
.. _live-test-server:
|
||||
|
||||
``LiveServerTestCase``
|
||||
|
||||
Reference in New Issue
Block a user