【问题标题】:Django testing commit_on_successDjango 测试 commit_on_success
【发布时间】:2015-08-29 00:04:52
【问题描述】:

我有一个函数,我已经用 @transaction.commit_on_success 进行了封装,并在其上运行 Django 单元测试。

函数太长,无法粘贴,但有一些伪代码是:

@transaction.commit_on_success
def func():
  order = Order.create()
  order.save()
  OrderItem.create(order=order)
  test = 10/0 # make sure we run into an error

然后在我的单元测试中我检查len(Order.objects.all()) == 0

我的函数正在返回一个有效的 Order 对象,因此事务正在提交。

我在这里做错了什么?

编辑:我在 Django 1.5

【问题讨论】:

    标签: python django django-database django-unittest


    【解决方案1】:

    想通了。

    我需要使用TransactionTestCase(1.5 没有文档)。

    TransactionTestCase 可以调用 commit 和 rollback 并观察这些调用对数据库的影响。

    我之前遇到过这个问题,但尝试将它与 TestCase 一起使用。它们是互斥的,您的单元测试只能使用一个或另一个。因为我们使用的是自定义测试类,所以我不得不进行一些操作,但现在一切都正常回滚了。

    看起来 Django 1.8 TestCase 现在也支持事务测试了:

    在旧版本的 Django 中,无法在 TestCase 中测试事务提交和回滚的效果。随着 Django 1.8 中旧式事务管理的弃用周期完成,TestCase 中不再禁用事务管理命令(例如 transaction.commit())。

    感谢 John 和 siracoj 的回答。无论如何,我最好从 1.5 升级;)

    【讨论】:

    • 我当然建议升级。 :)
    【解决方案2】:

    如果您使用的是 MySQL,您的表可能不支持事务。有关详细信息,请参阅transactions 上的 Django 文档。

    【讨论】:

    • 我正在使用 Postgres 并且已经搜索过文档。不过谢谢!
    【解决方案3】:

    您应该改用@transaction.atomic,commit_on_success 自 django 1.6 以来已被贬值,因为它不可靠。

    欲了解更多信息,请查看此答案:Is "transaction.atomic" same as "transaction.commit_on_success"?

    编辑(因为您使用的是 1.5):

    一个可能的解决方法是使用@transaction.commit_manually,如下所示:https://docs.djangoproject.com/en/1.5/topics/db/transactions/#django.db.transaction.commit_manually

    【讨论】:

    • 我们的堆栈使用的是 1.5。虽然我可以考虑升级 Django,但我更愿意尝试弄清楚我们当前版本中发生了什么。
    • 感谢您的编辑。我想我会继续这个策略。所以我假设这只是 commit_on_success 的一个错误?
    • @grokpot 是的,正如我链接的答案中所说的那样,它不可靠。它可能是由于该错误而提交的,或者回滚失败
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 2023-03-13
    • 2014-09-13
    • 2014-07-16
    相关资源
    最近更新 更多