Django TestCase assert запрос возвращает объект

Не знаю, почему я не могу найти документацию по этому вопросу, но:

    def test_invalid_trip_location_field_value(self):
        trip_location_field = TripLocationField.objects.filter(
            name='Fiji'
        ).first()
        self.assertEqual(len(trip_location_field), 1)

Это дает мне TypeError: object of type 'TripLocationField' has no len(). Как я могу утверждать, что объект существует?

Вызов first() возвращает объект TripLocationField, который вы определили в models.py. Нет никакого смысла вызывать len() на ОДНОМ объекте, потому что он не является коллекцией какого-либо вида.

Так что не звоните first():

trip_location_fields = TripLocationField.objects.filter(name='Fiji')`

Теперь у вас есть объект QuerySet, который вы можете вызвать count(), чтобы найти количество объектов:

self.assertEqual(trip_location_fields.count(), 1)

Обратите внимание, что этот тест выглядит так, как будто вы проверяете, что Django работает так, как он говорит. Хотя это хорошее упражнение для обучения, я рекомендую вам писать тесты, которые проверяют код, написанный вами. В частности, это означает, что вы должны вызвать функцию в вашем собственном коде или использовать тестовый клиен Django, чтобы сделать запрос к одной из ваших конечных точек как часть вашего теста. Тогда вы сможете утверждать, что функция или конечная точка, которую вы вызвали, делает то, что должна делать.

Как отмечает @Code-Apprentice, ваш .first() вернет модель объекта, или None, если такой объект не найден. Таким образом, мы можем проверить с помощью None.

Однако мы можем сделать его более удобным, определив свой собственный тест, который затем можно использовать повсюду:

def assertQuerySetContains(qs, msg=None):
    self.assertIsNotNone(
        qs.first(), msg or f'{qs} should contain at least one item'
    )

тогда мы можем проверить это с помощью:

def test_invalid_trip_location_field_value(self):
    self.assertQuerySetContains(TripLocationField.objects.filter(name='Fiji'))
Вернуться на верх