4

我有一个函数,我已经封装@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

4

3 回答 3

5

弄清楚了。

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

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

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

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

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

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

于 2015-08-30T00:45:46.447 回答
1

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

于 2015-08-29T05:13:41.513 回答
1

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

有关更多信息,请查看此答案:“transaction.atomic”与“transaction.commit_on_success”相同吗?

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

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

于 2015-08-29T05:27:33.780 回答