2013-04-17 7 views
14

내가 아주 간단한 뷰를 가지고 테스트 케이스.비교 검색어 세트는</p> <pre><code>def simple_view(request): documents = request.user.document_set.all() return render(request, 'simple.html', {'documents': documents}) </code></pre> <p>내가하는 오류를 밖으로 다음과 같은 방법을 내 테스트 케이스에 위의보기를 테스트하려면 다음과 같이

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입니다. querysets 인쇄를 시도했으며 두 가지 모두 절대적으로 동일합니다. 두 개체가 모두 동일한 경우 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 

답변

19

의 검색어 객체가 동일하지 않을 것이다 그 결과 (ds1.queryds2.query 비교). 처음 목록으로 설정 쿼리를 변환하면

, 당신은 보통의 비교 (그들은 물론 같은 정렬 순서를 가정)을 할 수 있어야한다 :

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

예. 방금 해결책을 찾았습니다. 감사. – Amyth

+1

또는 좀 더 간결하게 self.assertEqual (list (ds1), list (ds2)) – igniteflow

0

해결책을 발견. 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))) 
    # ... 
6

이 대안은 정렬이 필요하지 않습니다

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

assert reference를 참조하십시오.

참고 : django 1.4 이상에서만 가능합니다.

+0

시도해 보았지만 querysets은 항상 같지 않습니다. 그것을 사용했습니다 :'self.assertQuerysetEqual (qs1, map (repr, qs2), ordered = False)'. 이 스레드에서 : http://stackoverflow.com/a/14189017/821594 – stalk

+0

@stalk 왜 기본적으로 비교하기 위해'repr() '을 사용해야할까요? 그리고 양쪽 quesysets가 동등한 repr가 동일 할 것이라는 점을 예상되는 경우에, 맞습니까? –

+2

[docs] (https://docs.djangoproject.com/ko/1.5/topics/testing/overview/#django.test.TestCase.assertQuerysetEqual)에서 나는 당신의 예제가 효과가 있다고 생각했다. 하지만 그렇지 않습니다 ...'repr' func은 첫 번째 비 목록 쿼리 세트에만 적용되고 두 번째 목록은 명시 적으로 적용되어야합니다. 장고 1.4.5 :'qs1 = M.objects.all(); qs2 = M.objects.all() # (동일)','self.assertQuerysetEqual (qs1, list (qs2), ordered = False)'<- 실패; 'self.assertQuerysetEqual (qs1, map (repr, qs2), ordered = False)'<패스; – stalk