Как проверить, что запросы Django равны?
Я пытаюсь проверить свои взгляды Django. Это представление передает запрос шаблону:
def merchant_home(request, slug):
merchant = Merchant.objects.get(slug=slug)
product_list = merchant.products.all()
return render_to_response('merchant_home.html',
{'merchant': merchant,
'product_list': product_list},
context_instance=RequestContext(request))
и тест:
def test(self):
"Merchant home view should send merchant and merchant products to the template"
merchant = Merchant.objects.create(name='test merchant')
product = Product.objects.create(name='test product', price=100.00)
merchant.products.add(product)
test_client = Client()
response = test_client.get('/' + merchant.slug)
# self.assertListEqual(response.context['product_list'], merchant.products.all())
self.assertQuerysetEqual(response.context['product_list'], merchant.products.all())
редактировать
Я использую себя.assertQuerysetEqual вместо себя.assertListEqual. К сожалению, это все еще не работает, и терминал отображает это:
['<Product: Product object>'] != [<Product: Product object>]
assertListEqual вызывает: объект' QuerySet 'не имеет атрибута 'difference'
assertEqual тоже не работает, хотя self.assertSetEqual(response.context['product_list'][0], merchant.products.all()[0])
проходит.
Я предполагаю, что это потому, что запросы являются разными объектами, даже если они содержат одни и те же экземпляры модели.
Как проверить, что два запроса содержат одни и те же данные? Я каждый тестирую это правильно? Это мой 4-й день обучения Django, поэтому я хотел бы знать лучшие практики, если это возможно. Спасибо.
6 ответов
использовать assertQuerysetEqual, который построен для сравнения двух запросов для вас. Вам нужно будет подкласс Django's django.test.TestCase
чтобы он был доступен в ваших тестах.
по умолчанию assertQuerysetEqual
использует repr()
по первому аргументу. Вот почему у вас возникли проблемы со строками в сравнении queryset.
чтобы обойти это, вы можете переопределить transform
аргумент С lambda
функция, которая не использует repr()
:
self.assertQuerysetEqual(queryset_1, queryset_2, transform=lambda x: x)
у меня была та же проблема. Второй аргумент assertQuerysetEqual
должен быть список ожидаемых repr () s в виде строк. Вот пример из набора тестов Django:
self.assertQuerysetEqual(c1.tags.all(), ["<Tag: t1>", "<Tag: t2>"], ordered=False)
Я закончил решение этой проблемы с помощью map
to repr()
каждая запись в queryset внутри self.assertQuerysetEqual
вызова, например,
self.assertQuerysetEqual(queryset_1, map(repr, queryset_2))
альтернативный, но не обязательно лучший метод может выглядеть так (например, контекст тестирования в представлении) при использовании pytest:
all_the_things = Things.objects.all()
assert set(list(response.context_data['all_the_things'])) == set(list(all_the_things))
это преобразует его в список, а затем набор, который непосредственно сопоставим с другим набором. Будьте осторожны с поведением set
хотя это может быть не совсем то, что вы хотите, так как он удалит дубликаты.