私は今日これを見るのに少し時間を費やし、次のデコレータを思いついた:
from functools import wraps
from django.db import transaction
from mock import patch
def rollback_db_changes(func):
"""Decorate a function so that it will be rolled back once completed."""
@wraps(func)
@transaction.commit_manually
def new_f(*args, **kwargs):
def fake_commit(using=None):
# Don't properly commit the transaction, so we can roll it back
transaction.set_clean(using)
patcher = patch('django.db.transaction.commit', fake_commit)
patcher.start()
try:
return func(*args, **kwargs)
finally:
patcher.stop()
transaction.rollback()
return new_f
パッチを適用して、Djangoテストクライアントがトランザクションをロールバックできずにトランザクションを閉じないようにします。これにより、次のテストに合格できます。
from django.contrib.auth.models import User
@rollback_db_changes
def test_allowed_access():
user = User.objects.create(username='test_user')
eq_(1, User.objects.count())
@rollback_db_changes
def test_allowed_access_2():
user = User.objects.create(username='test_user')
eq_(1, User.objects.count())
以前は、実行する2番目のテストで、重複したユーザー名を持つユーザーを作成できませんでした。