2013-07-16 1 views
13

장고보기를 테스트하려고합니다. 이 뷰는 템플릿에 검색어 세트를 전달합니다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)) 

및 테스트 :

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()) 

편집 내가 대신 self.assertListEqual의 self.assertQuerysetEqual를 사용하고 합니다. 불행하게도이 여전히 작동하지 않고 터미널 표시이 : ['<Product: Product object>'] != [<Product: Product object>]


assertListEqual 제기 : '검색어 세트'객체는 assertEqual는 self.assertSetEqual(response.context['product_list'][0], merchant.products.all()[0]) 통과 않지만, 하나가 작동하지 않는 어떤 속성 '차이' 이 없습니다.

동일한 모델 인스턴스가 포함되어 있어도 QuerySets가 다른 개체이기 때문입니다.

두 QuerySets에 동일한 데이터가 포함되어 있는지 테스트하려면 어떻게해야합니까? 나는이 모든 것을 정확하게 테스트하고 있는가? 가능하다면 모범 사례를 알고 싶습니다. 이것은 장고를 배운 제 4 일째입니다. 감사.

답변

15

두 개의 쿼리 세트를 비교할 수 있도록 만들어진 assertQuerysetEqual을 사용하십시오. Django의 django.test.TestCase 하위 클래스를 테스트해야 사용할 수 있습니다.

+6

신난다,이, 도움이됩니다 : AssertionError를 : [ '< 제품 : Product object> ']! = [] 유일한 차이점은 첫 번째 제품 개체 주위에 따옴표가 있다는 것입니다. 둘 다 QuerySet입니다. – jz999

+0

새 테스트 코드로 질문을 업데이트하십시오. :) – girasquid

+0

그냥, 감사합니다 – jz999

5

방금 ​​같은 문제가있었습니다. assertQuerysetEqual의 두 번째 인수는 예상 repr()을 문자열로 나열해야합니다.

self.assertQuerysetEqual(c1.tags.all(), ["<Tag: t1>", "<Tag: t2>"], ordered=False) 
+1

참조 http://stackoverflow.com/a/14189017/678486 (전체 공개 이것은 내 대답이다). –

1

대안하지만 반드시 더 나은 방법은 (예를 들어,보기에서 테스트 컨텍스트를) 다음과 같을 수 pytest 사용 :

all_the_things = Things.objects.all() 
assert set(list(response.context_data['all_the_things'])) == set(list(all_the_things)) 
을 여기 장고 테스트 스위트에서 예입니다

이것은 목록으로 변환 한 다음 다른 세트와 직접 비교할 수있는 세트로 변환합니다. set의 동작에주의하십시오. 복제본을 제거하기 때문에 원하는 내용이 아닐 수도 있습니다.

1

기본적으로 assertQuerysetEqual은 첫 번째 인수에 repr()을 사용하므로 쿼리 세트 비교에서 문자열에 문제가있는 이유입니다.

는이 문제를 해결하려면 할 수 있습니다 사용하지 않는 lambda 기능 override the transform argument repr() :

지금 내 테스트는 이것 때문에 실패하더라도
self.assertQuerysetEqual(queryset_1, queryset_2, transform=lambda x: x)