如何在不清除数据库的情况下测试Django on_commit挂钩?

F.X*_*.X. 10 python testing django transactions

on_commit功能已经被添加到Django的1.9到能够在当前事务提交后触发一个动作(如芹菜任务).

他们后来在文档中提到应该TransactionTestCase用来测试依赖于该功能的功能.但是,与TestCase(使用事务并将其回滚)不同,TransactionTestCase在每次测试后清空整个数据库.

不幸的是,我有数据迁移在数据库中预加载一些有用的数据,这意味着在第一次测试清除数据库后,后续测试不再起作用.

我最后通过嘲笑来诉诸于一个肮脏的伎俩on_commit:

with mock.patch.object(django.db.transaction, 'on_commit', lambda t: t()):
    test_something()
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?

Sla*_*ava 9

从版本 3.2 开始,Django 有一种内置方法来测试 on_comit 挂钩。例子:

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')
Run Code Online (Sandbox Code Playgroud)

这是官方文档:https://docs.djangoproject.com/en/stable/topics/testing/tools/#django.test.TestCase.captureOnCommitCallbacks


小智 7

只要继续使用测试用例和假承诺posponed行动迫使执行中run_and_clear_commit_hooks.查看这篇文章:

https://medium.com/gitux/speed-up-django-transaction-hooks-tests-6de4a558ef96