select_related queryset objects example cual consultas avanzadas python django django-testing

python - objects - ¿Cómo pruebo que Django QuerySets sea igual?



objects.filter django (6)

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.assertQuerysetEqual en lugar de self.assertListEqual. Desafortunadamente, esto todavía no funciona, y el terminal muestra esto: [''<Product: Product object>''] != [<Product: Product object>]

assertListEqual plantea: el objeto ''QuerySet'' no tiene atributo ''diferencia'' assertEqual tampoco funciona, aunque self.assertSetEqual(response.context[''product_list''][0], merchant.products.all()[0]) 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? ¿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.


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(), ["<Tag: t1>", "<Tag: t2>"], ordered=False)


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


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 solucionar esto, puede anular el argumento de transform con una función lambda que no utiliza repr() :

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


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 quiere, ya que eliminará los duplicados.


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.