比较django测试用例中的查询集
我有一个非常简单的观点如下比较django测试用例中的查询集,django,compare,testcase,django-queryset,Django,Compare,Testcase,Django Queryset,我有一个非常简单的观点如下 def simple_view(request): documents = request.user.document_set.all() return render(request, 'simple.html', {'documents': documents}) 为了在我的测试用例中测试上面的视图,我使用了下面的错误排除方法 Class SomeTestCase(TestCase): # ... def test_simple_v
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不是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
如果queryset对象是不同查询的结果,即使它们的结果中的值相同(比较
ds1.query
和ds2.query
)
如果首先将查询集转换为列表,则应该能够进行正常比较(当然,假设它们具有相同的排序顺序):
找到了解决办法。我们需要将
查询集
转换为排序列表,然后才能进行比较。事情如下
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)))
# ...
此备选方案不需要排序:
self.assertQuerysetEqual(qs1, list(qs2), ordered=False)
看
注意:仅适用于django 1.4+。适用于me的
转换
选项:
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)
尝试过这一点,但查询集并非总是相等的(即使它们是相同的)!使用:
self.assertquerystequal(qs1,map(repr,qs2),ordered=False)
。从这条线:@stable我真的不知道为什么。。。默认情况下,应该使用repr()
进行比较。如果两个quesysets相等,那么repr应该是相同的,对吗?看看我的想法,你的例子就行了。但它不。。。看起来repr
func仅应用于第一个非列表查询集,而对于第二个列表,必须显式应用它。对于django 1.4.5:qs1=M.objects.all();qs2=M.objects.all()#(相同)
,self.assertquerystequal(qs1,list(qs2),ordered=False)
Yesassertquerystequals
在2.1中失败,即使传递了相同的queryset引用,例如,assertquerystequals(qs1,qs1)
——但stape的解决方案确实有效。或者更简洁地说,self.assertEqual(list(ds1),list(ds2))如果您的查询集太大,无法进行计算,那么您可能可以使用django,或者我们可以使用set()
,而不是list()
,以独立于排序顺序。True,可以将它们放在一个集合中,但这也可能隐藏一个查询集合有重复行,而另一个查询集合没有重复行的问题。@MattiJohn:你完全正确。事实上,我自己也遇到了这样的问题。我将坚持使用list()
。谢谢
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)