¿Cómo pruebo que Django QuerySets sea igual?

Estoy tratando de probar mis puntos de vista Django. Esta vista pasa un QuerySet a la plantilla:

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)) 

y prueba:

  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()) 

EDITAR Estoy usando self.assertQuerysetEqua l en lugar de self.assertListEqual . Desafortunadamente, esto todavía no funciona, y el terminal muestra esto: [''] != []


assertListEqual plantea: 'QuerySet' object has no attribute 'difference' y assertEqual tampoco funciona, aunque self.assertSetEqual(response.context['product_list'][0], merchant.products.all()[0]) no pasa .

Supongo que esto se debe a que los QuerySets son objetos diferentes a pesar de que contienen las mismas instancias del modelo.

¿Cómo pruebo que dos QuerySets contengan los mismos datos? ¿Incluso estoy probando esto correctamente? Este es mi cuarto día de aprendizaje de Django, así que me gustaría conocer las mejores prácticas, si es posible. Gracias.

Use assertQuerysetEqual , que está diseñado para comparar los dos querysets por usted. Deberá subclasificar el django.test.TestCase de Django para que esté disponible en sus pruebas.

Por defecto, assertQuerysetEqual usa repr() en el primer argumento. Esta es la razón por la que tenía problemas con las cadenas en la comparación queryset.

Para evitar esto, puede anular el argumento de transform con una función lambda que no usa repr() :

 self.assertQuerysetEqual(queryset_1, queryset_2, transform=lambda x: x) 

Acabo de tener el mismo problema. El segundo argumento de assertQuerysetEqual debe ser una lista de los repr () esperados como cadenas. Aquí hay un ejemplo del conjunto de pruebas de Django:

 self.assertQuerysetEqual(c1.tags.all(), ["", ""], ordered=False) 

Terminé resolviendo este problema usando map para repr() cada entrada en el queryset dentro de la llamada self.assertQuerysetEqual , por ejemplo

 self.assertQuerysetEqual(queryset_1, map(repr, queryset_2)) 

Un método alternativo, pero no necesariamente mejor, podría tener este aspecto (probando el contexto en una vista, por ejemplo) cuando se usa pytest:

 all_the_things = Things.objects.all() assert set(list(response.context_data['all_the_things'])) == set(list(all_the_things)) 

Esto lo convierte en una lista, luego en un conjunto, que es directamente comparable con otro conjunto. Sin embargo, tenga cuidado con el comportamiento del set , puede que no sea exactamente lo que desea, ya que eliminará los duplicados.

Descubrí que el uso de self.assertCountEqual(queryset1, queryset2) también resuelve el problema.