Подтвердить что ты не робот

Сравнение запросов в django TestCase

У меня очень простое представление:

def simple_view(request):
    documents = request.user.document_set.all()
    return render(request, 'simple.html', {'documents': documents})

Чтобы проверить приведенное выше представление в моем тестовом примере, у меня есть следующий метод, который содержит ошибки.

Class SomeTestCase(TestCase):
    # ...
    def test_simple_view(self):
        # ... some other checks
        docset = self.resonse.context['documents']
        self.assertTrue(self.user.document_set.all() == docset) # This line raises an error
    # ...

Ошибка, которую я получаю, составляет AssertionError: False is not true. Я попробовал распечатать оба запроса, и оба они абсолютно идентичны. Зачем ему возвращать False, когда оба объекта идентичны? Любые идеи?

В настоящее время, чтобы преодолеть это, я использую неприятный взлом проверки длины следующим образом:

ds1, ds2 = self.response.context['documents'], self.user.document_set.all()
self.assertTrue(len([x for x in ds1 if x in ds2]) == len(ds1) == len(ds2)) # Makes sure each entry in ds1 exists in ds2
4b9b3361

Ответ 1

Объекты запроса не будут идентичны, если они являются результатом разных запросов, даже если они имеют одинаковые значения в их результате (сравните ds1.query и ds2.query).

Если вы сначала конвертируете запрос в список, вы должны иметь возможность нормального сравнения (при условии, что они имеют одинаковый порядок сортировки, конечно):

self.assertEqual(list(ds1), list(ds2))

Ответ 2

Этот вариант не нуждается в сортировке:

self.assertQuerysetEqual(qs1, list(qs2), ordered=False)

Смотрите ссылку assert.

Примечание. Только для django 1.4 +.

Ответ 3

Найден решение. Нам нужно преобразовать Querysets в отсортированные списки, прежде чем мы сможем их сравнить. Что-то следующее.

Class SomeTestCase(TestCase):
    # ...
    def test_simple_view(self):
        # ... some other checks
        docset1 = self.resonse.context['documents']
        docset2 = self.user.document_set.all()
        self.assertTrue(list(sorted(docset1)) == len(sorted(docset)))
    # ...

Ответ 4

Для меня работает опция transform:

    def subject(self):
        return Mission.objects.add_keynest_api_token().filter(keynest_api_token__isnull=False)

    def test_mission_has_property(self):
        self.mission.appartement = self.property
        self.mission.save()
        self.assertQuerysetEqual(self.subject(), [self.mission], transform=lambda x: x)