我如何测试Django QuerySets是否相等?

jz9*_*999 25 python django django-queryset django-testing

我正在尝试测试我的Django视图.此视图将QuerySet传递给模板:

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))
Run Code Online (Sandbox Code Playgroud)

并测试:

  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())
Run Code Online (Sandbox Code Playgroud)

编辑 我用的是self.assertQuerysetEqual而不是self.assertListEqual.不幸的是,这仍然无效,终端显示: ['<Product: Product object>'] != [<Product: Product object>]


assertListEqual提出:'QuerySet' object has no attribute 'difference'并且 assertEqual也不起作用,虽然self.assertSetEqual(response.context['product_list'][0], merchant.products.all()[0])确实通过了.

我假设这是因为QuerySets是不同的对象,即使它们包含相同的模型实例.

如何测试两个QuerySets包含相同的数据?我甚至正确测试了这个?这是我第四天学习Django,所以如果可能的话,我想了解最佳实践.谢谢.

gir*_*uid 25

使用assertQuerysetEqual,它是为了比较两个查询集而构建的.您需要继承Django的子类django.test.TestCase才能在测试中使用它.

  • 太棒了,这很有帮助,虽然现在我的测试失败了因为:AssertionError:['<Product:Product object>']!= [<Product:Product object>]我看到的唯一区别是第一个引号周围有引号产品对象.它们都是类QuerySet (12认同)

dsp*_*ejs 21

默认情况下,assertQuerysetEqual使用repr()第一个参数.这就是您在查询集比较中遇到字符串问题的原因.

要解决此问题,您可以使用不使用的函数覆盖transform参数:lambdarepr()

self.assertQuerysetEqual(queryset_1, queryset_2, transform=lambda x: x)
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个 :-) (3认同)

sk1*_*k1p 8

我刚遇到同样的问题.第二个参数assertQuerysetEqual需要是预期的repr()作为字符串的列表.以下是Django测试套件的示例:

self.assertQuerysetEqual(c1.tags.all(), ["<Tag: t1>", "<Tag: t2>"], ordered=False)
Run Code Online (Sandbox Code Playgroud)