27

我有一个非常简单的看法如下

def simple_view(request):
    documents = request.user.document_set.all()
    return render(request, 'simple.html', {'documents': documents})

为了在我的测试用例中测试上述视图,我有以下方法出错。

Class SomeTestCase(TestCase):
    # ...
    def test_simple_view(self):
        # ... some other checks
        docset = self.resonse.context['documents']
        self.assertTrue(self.user.document_set.all() == docset) # This line raises an error
    # ...

我得到的错误是AssertionError: False is not true。我已经尝试打印两个查询集,并且两者都完全相同。为什么False当两个对象相同时它会返回?有任何想法吗 ?

目前为了克服这个问题,我正在使用一种令人讨厌的检查长度的方法,如下所示:

ds1, ds2 = self.response.context['documents'], self.user.document_set.all()
self.assertTrue(len([x for x in ds1 if x in ds2]) == len(ds1) == len(ds2)) # Makes sure each entry in ds1 exists in ds2
4

5 回答 5

39

如果查询集对象是不同查询的结果,即使它们在结果中具有相同的值(比较ds1.queryds2.query),它们也将不相同。

如果您首先将查询集转换为列表,您应该能够进行正常比较(当然假设它们具有相同的排序顺序):

self.assertEqual(list(ds1), list(ds2))
于 2013-04-17T11:45:13.247 回答
7

这种替代方法不需要排序:

self.assertQuerysetEqual(qs1, list(qs2), ordered=False)

请参阅断言参考

注意:仅适用于 django 1.4+。

于 2013-04-17T13:31:24.190 回答
1

您可以使用assertQuerysetEqual方法比较两个查询集,而无需转换为列表。True如果查询集的值相等,这将返回,无论查询是否不同。

一个问题是,此方法repr在比较之前将函数作为转换应用于第一个参数中的每个对象,这在比较两个实际相等的查询集时可能导致以下错误:

AssertionError: Lists differ: ['<Object: id1'] != [<Object: id1>]

解决方案是传递您自己的transform函数来使用,而不是repr

self.assertQuerysetEqual(qs1, qs2, transform=lambda x: x)
于 2021-07-01T14:32:12.837 回答
1

For me works the transform option:

    def subject(self):
        return Mission.objects.add_keynest_api_token().filter(keynest_api_token__isnull=False)

    def test_mission_has_property(self):
        self.mission.appartement = self.property
        self.mission.save()
        self.assertQuerysetEqual(self.subject(), [self.mission], transform=lambda x: x)

于 2019-10-04T10:26:46.967 回答
-1

找到了解决方案。我们需要先转换Querysets为排序列表,然后才能比较它们。东西如下。

Class SomeTestCase(TestCase):
    # ...
    def test_simple_view(self):
        # ... some other checks
        docset1 = self.resonse.context['documents']
        docset2 = self.user.document_set.all()
        self.assertTrue(list(sorted(docset1)) == len(sorted(docset)))
    # ...
于 2013-04-17T11:46:37.843 回答