#30457: on_commit should be triggered in a TestCase
------------------------------------+-------------------------------------
Reporter: Bernhard Mäder | Owner: Swatantra
Type: New feature | Status: assigned
Component: Documentation | Version: master
Severity: Normal | Resolution:
Keywords: on_commit TestCase | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
------------------------------------+-------------------------------------
Comment (by Simon Charette):
FWIW we switched to an approach that defers hooks execution to the end of
the context manager instead of executing immediately by default to
properly mimic what an atomic block would do.
{{{#!python
@contextmanager
def execute_on_commit(immediately=False, using=None):
"""
Context manager capturing transaction.on_commit() calls and executing
them on exit or immediately if specified.
This is required when using a subclass of django.test.TestCase as all
tests are wrapped in a transaction that never gets committed.
"""
for_alias = DEFAULT_DB_ALIAS if using is None else using
deferred = []
def side_effect(func, using=None):
alias = DEFAULT_DB_ALIAS if using is None else using
if alias != for_alias:
return
if immediately:
return func()
deferred.append(func)
with mock.patch('django.db.transaction.on_commit') as patch:
patch.side_effect = side_effect
yield patch
for func in deferred:
func()
}}}
For example this was necessary to test edge cases such as lazy loading
failure of deleted objects
{{{#!python
parent = Node.objects.create()
node = Node.objects.create(parent=parent)
with self.immediate_on_commit():
# imagine a pre-delete signal scheduling the following hook.
transaction.on_commit(lambda: node.parent.something())
parent.delete()
}}}
Would fail in a normal scenario because `parent` doesn't exist anymore one
the transaction commits. This is covered by `execute_on_commit`.
--
Ticket URL: <https://code.djangoproject.com/ticket/30457#comment:10>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/064.79e377e855845948157822ee6cdbb8c0%40djangoproject.com.