Юнит-тест Django исправляет идентификатор строки базы данных

from django.test import TestCase

class DefTests(TestCase):

    def setUp(self): 
       # first made the label
       UserType(label="mylabel").save() ## UserType is model object, and I made the first row , the id is supposed to be 1

    def test_my(self):
       u = UserType.objects.get(id=1) # UserType.DoesNotExis error

Полагаю, что в тестовом режиме реальная вставка не выполняется, поэтому id не фиксируется. Я прав?

Тогда, есть ли способ исправить id заранее, прежде чем делать test_****?

Обычно вы прикрепляете объект или его идентификатор к экземпляру теста, так:

from django.test import TestCase


class DefTests(TestCase):
    def setUp(self):
        # first made the label
        user_type = UserType.objects.create(label='mylabel')
        self.user_type_id = user_type.pk

    def test_my(self):
        u = UserType.objects.get(id=self.user_type_id)

Другим вариантом является применение первичного ключа, однако потенциальная проблема заключается в том, что тесты могут выполняться в любом порядке, поэтому, строго говоря, возможно, что уже существует UserType с таким идентификатором, а не тот, который мы хотим сохранить:

from django.test import TestCase


class DefTests(TestCase):
    def setUp(self):
        # first made the label
        user_type = UserType.objects.create(pk=1, label='mylabel')

    def test_my(self):
        u = UserType.objects.get(pk=1)

При этом принудительное использование первичных ключей выглядит плохой идеей: обычно первичный ключ должен рассматриваться как "значение черного ящика": то, что он является int, - это скорее деталь реализации, поскольку, например, сложение двух первичных ключей не имеет особого смысла.


Note: It is usually better to use .create(…) [Django-doc] to create a record in the database, than to instantiate a model object and .save(…) [Django-doc] it: when you save a model instance, it first looks if there is already a record, so this can increase the number of queries on the database.

Вернуться на верх