comparing querysets in django TestCase

无人久伴 提交于 2019-12-12 09:29:41

问题


I have a very simple view as follows

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

To test the above view in my test case i have the following method which errors out.

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
    # ...

The error i get is AssertionError: False is not true. I have tried printing both the querysets and both are absolutely identical. Why would it return False when both the objects are identical ? Any Ideas ?

Currently to overcome this, I am using a nasty hack of checking lengths as follows:

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

回答1:


The queryset objects will not be identical if they are the result of different queries even if they have the same values in their result (compare ds1.query and ds2.query).

If you convert the query set to a list first, you should be able to do a normal comparison (assuming they have the same sort order of course):

self.assertEqual(list(ds1), list(ds2))



回答2:


This alternative doesn't need sorting:

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

See the assert reference.

Note: Only for django 1.4+.




回答3:


Found a solution. We need to convert Querysets to sorted lists before we can compare them. Something as follows.

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



回答4:


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)



来源:https://stackoverflow.com/questions/16058571/comparing-querysets-in-django-testcase

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!