我有一个函数,我已经包含在@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答案 0 :(得分:3)
想出来。
我需要使用TransactionTestCase(没有1.5的文档)。
TransactionTestCase可以调用commit和rollback,并观察这些调用对数据库的影响。
之前我遇到过这个问题,但试图将它与TestCase结合使用。它们是互斥的,您的单元测试只能使用一个或另一个。因为我们使用的是自定义测试类,所以我必须进行一些操作,但现在一切都正常回滚。
看起来Django 1.8 TestCase现在支持事务测试:
在旧版本的Django中,无法在TestCase中测试事务提交和回滚的影响。随着Django 1.8中旧式事务管理的弃用周期的完成,TestCase中不再禁用事务管理命令(例如transaction.commit())。
感谢John和siracoj的回答。我反正从1.5升级可能是最好的;)
答案 1 :(得分:1)
如果您使用的是MySQL,那么您的表可能不支持交易。有关详细信息,请参阅transactions上的Django文档。
答案 2 :(得分:1)
你应该使用@transaction.atomic
代替,自django 1.6以来,commit_on_success已被折旧,因为它不可靠。
有关详情,请查看以下答案: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