Не удалось найти объект из БД сразу после того, как я его создал - PullRequest
0 голосов
/ 20 апреля 2019

Я тестировал создание пользователя, создав TestCase, и его не удалось найти сразу после его создания.

Я пытался очистить кэш, вызвав .refresh_from_db(), но это не такt работа.

Вот мой TestCase:

class SuperStrangeTest(TestCase):
    def test_super_strange(self):
        john = User.objects.create()
        john.refresh_from_db()

        print('!=====START' * 10)
        print(User.objects.count())
        print(User.objects.all())
        self.assertIsNotNone(User.objects.filter().first()) # None of assertions below would be right
        self.assertIsNotNone(User.objects.filter(id=john.id).first())
        self.assertTrue(User.objects.filter(id=john.id).exists())

Моя команда для запуска этого теста:

./manage.py test --noinput --failfast --keepdb links.tests.SuperStrangeTest.test_super_strange

Результат иногда отправлялсяверно, но в большинстве случаев он просто сломан.

Using existing test database for alias 'default'...
/Users/oldcai/.virtualenvs/web/lib/python3.7/site-packages/grequests.py:21: MonkeyPatchWarning: Patching more than once will result in the union of all True parameters being patched
  curious_george.patch_all(thread=False, select=False)
System check identified no issues (0 silenced).
!=====START!=====START!=====START!=====START!=====START!=====START!=====START!=====START!=====START!=====START
1
<QuerySet [<User: >]>
F
======================================================================
FAIL: test_super_strange (links.tests.SuperStrangeTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/oldcai/programs/python/webproject/zine/links/tests.py", line 41, in test_super_strange
    self.assertIsNotNone(User.objects.filter().first())
AssertionError: unexpectedly None

----------------------------------------------------------------------

Ran 1 test in 0.130s

FAILED (failures=1)
Preserving test database for alias 'default'...

Ошибки других строк:

======================================================================
FAIL: test_super_strange (links.tests.SuperStrangeTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/oldcai/programs/python/webproject/links/tests.py", line 35, in test_super_strange
    self.assertTrue(User.objects.filter(id=john.id).exists())
AssertionError: False is not true

----------------------------------------------------------------------
======================================================================
FAIL: test_super_strange (links.tests.SuperStrangeTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/oldcai/programs/python/webproject/links/tests.py", line 35, in test_super_strange
    self.assertTrue(User.objects.filter(id=john.id).exists())
AssertionError: False is not true

----------------------------------------------------------------------

Ответы [ 2 ]

0 голосов
/ 20 апреля 2019

После более глубокой диагностики этой проблемы выясняется, что эта ошибка связана с моей настройкой DATABASE_ROUTERS.

Я направляю часть операций чтения на случайную подчиненную базу данных только для чтения в производстве на балансировкунагрузка чтения.

В TestCase я установил конфиги ведомой базы данных равными значениям по умолчанию.

DATABASE = {
    'ENGINE': 'django.db.backends.postgresql',
    'ATOMIC_REQUESTS': False,
    'CONN_MAX_AGE': 0,
    'NAME': 'test',
    'USER': 'test',
    'PASSWORD': 'test',
    'HOST': '',
    'PORT': '',
}

DATABASES = {
    'default': DATABASE,
    'replica1': DATABASE,
}

Но он все еще не может запросить результат с помощью replica1 сразу после записи, вставленной в базу данных default.

Когда маршрутизатор случайным образом выбирает базу данных default в качестве базы для чтения, TestCase будет проходить, в противном случае произойдет сбой.

0 голосов
/ 20 апреля 2019

Попробуйте заполнить поля вашей модели.Это базовая модель Django User - требует имя пользователя и пароль.Также для создания пользователя django - используйте функцию create_user, эта функция будет хэшировать пароль для вас.Попробуйте исправить свой код так:

...
john = User.objects.create_user(username='john', password='password')
...
...