У меня есть модель Django с "названием" CharField(unique=True)
. У меня есть модульный тест, который утверждает, что создание второго экземпляра с тем же заголовком вызывает ошибку IntegrityError
. (Я использую pytest и pytest-django.)
У меня есть что-то вроде:
class Foo(models.Model):
title = models.CharField(unique=True)
def test_title_is_unique(db):
Foo.objects.create(title='foo')
with pytest.raises(IntegrityError):
Foo.objects.create(title='foo')
Это работает нормально, за исключением того, что приведенный выше код не включает код очистки. pytest-django не очищает базу данных за вас, поэтому вам необходимо зарегистрировать обработчики очистки при создании или сохранении экземпляра модели. Что-то вроде этого:
def test_title_is_unique(request, db):
foo = Foo.objects.create(title='foo')
request.addfinalizer(foo.delete)
with pytest.raises(IntegrityError):
Foo.objects.create(title='foo')
Хорошо, это нормально. Но что, если второй вызов .create()
окажется ошибочным? Я все еще хочу очистить этот экземпляр, но только если он (ошибочно) будет создан.
Вот на чем я остановился:
def test_title_is_unique(request, db):
foo = Foo.objects.create(title='foo')
request.addfinalizer(foo.delete)
try:
with pytest.raises(IntegrityError):
new_foo = Foo.objects.create(title='foo')
finally:
if 'new_foo' in locals():
request.addfinalizer(new_foo.delete)
Это не кажется особенно элегантным или Pythonic, не говоря уже о том, что есть куча строк кода, которые действительно не должны запускаться.
Как я могу гарантировать, что второй экземпляр модели будет очищен, если он создан, но с меньшим количеством обручей для перехода и/или с использованием меньшего количества строк кода?