Поведение функции Django Model меняется в зависимости от количества выполняемых тестов
У меня есть потребность в уникальном идентификаторе в моем Django коде. Я написал простую модель следующего вида
class UniqueIDGenerator(models.Model):
nextID = models.PositiveIntegerField(blank=False)
@classmethod
def getNextID(self):
if(self.objects.filter(id=1).exists()):
idValue = self.objects.get(id=1).nextID
idValue += 1
self.objects.filter(id=1).update(nextID=idValue)
return idValue
tempObj = self(nextID=1)
tempObj.save()
return tempObj.nextID
Затем я написал модульный тест следующим образом:
class ModelWorking(TestCase):
def setUp(self):
return None
def test_IDGenerator(self):
returnValue = UniqueIDGenerator.getNextID()
self.assertEqual(returnValue, 1)
returnValue = UniqueIDGenerator.getNextID()
self.assertEqual(returnValue, 2)
return None
Когда я запускаю этот тест сам по себе, он работает нормально. Никаких проблем.
Когда я запускаю этот тест как набор, который включает в себя кучу других модульных тестов (которые также включают вызовы getNextID()), этот тест не работает. getNextID() всегда возвращает 1. Почему так происходит?
Я понял это.
Django запускает каждый тест в транзакции для обеспечения изоляции. Doc link.
Поскольку другие мои тесты делают вызов getNextID(), первый ряд удаляется после завершения первого теста, который делает такой вызов. Последующие тесты никогда не находят (id=1), из-за чего все последующие вызовы возвращают значение 1.
Хотя я не думаю, что столкнусь с такой ситуацией в производстве, я пошел вперед и изменил свой код, чтобы использовать .first() вместо (id=1). Вот так
def getNextID(self):
firstRow = self.objects.first()
if(firstRow):
Такой способ, как мне кажется, лучше справится с любым будущим сценарием, когда таблица базы данных может быть опустошена.