[Django]-Django Unit Test Assert Database Transaction is Active

2๐Ÿ‘

โœ…

We managed to achieve this by adding the following function to the test class.

def assert_inside_atomic_block(self, using=None):
    """
    Returns a function that will assert we are inside an atomic transaction block. The purpose of this is to allow
    us to inject this assertion inside methods where we want to verify that a transaction is active.

    Does not work with django.db.TransactionTestCase because it automatically wraps each test in a transaction.
    """

    if issubclass(self.__class__, TransactionTestCase):
        raise AssertionError('Cannot determine if code is run inside a transaction with a TransactionTestCase')

    def _assert_inside_atomic_block(*args, **kwargs):
        if not get_connection(using=using).in_atomic_block:
            raise AssertionError('Not inside an atomic transaction block')

    return _assert_inside_atomic_block

Which can then be used in a test as follows:

@patch('function_we_will_patch_to_assert_transaction_is_open'):
def test_function_under_test__transaction_is_active(self, patched_fn):
    patched_fn.side_effect = self.assert_inside_atomic_block()

    function_under_test()

One important point to note: This technique does not work with test classes based on django.test.TransactionTestCase โ€“ because this wraps every test in a transaction the assertion will never fail.

๐Ÿ‘คrobjohncox

Leave a comment