How do I test Django QuerySets are equal?

jz999 picture jz999 · Jul 16, 2013 · Viewed 16.1k times · Source

I am trying to test my Django views. This view passes a QuerySet to the template:

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

and test:

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

EDIT I am using self.assertQuerysetEqual instead of self.assertListEqual. Unfortunately this still doesn't work, and the terminal displays this: ['<Product: Product object>'] != [<Product: Product object>]


assertListEqual raises: 'QuerySet' object has no attribute 'difference' and assertEqual does not work either, although self.assertSetEqual(response.context['product_list'][0], merchant.products.all()[0]) does pass.

I assume this is because the QuerySets are different objects even though they contain the same model instances.

How do I test that two QuerySets contain the same data? I am even testing this correctly? This is my 4th day learning Django so I would like to know best practices, if possible. Thanks.

Answer

girasquid picture girasquid · Jul 16, 2013

Use assertQuerysetEqual, which is built to compare the two querysets for you. You will need to subclass Django's django.test.TestCase for it to be available in your tests.