2013-07-16 20 views
13

Django görünümlerimi test etmeye çalışıyorum. Bu görüş şablona bir Sorgu Kümesi geçirir:Django QuerySets'in eşit olduğunu nasıl test ederim?

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

ve test:

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

DÜZENLEME yerine self.assertListEqual ait self.assertQuerysetEqual kullanıyorum . Ne yazık ki bu hala çalışır ve yok terminali görüntüler bu: ['<Product: Product object>'] != [<Product: Product object>]


assertListEqual yükseltir: 'QuerySet' nesne assertEqual self.assertSetEqual(response.context['product_list'][0], merchant.products.all()[0]) geçmesi olmasına rağmen, ya da çalışmaz hiçbir özellik 'fark' sahiptir.

Bunun nedeni, QuerySet'lerinin aynı model örneklerini içermelerine rağmen farklı nesneler oldukları için farz ediyorum.

İki QuerySets'in aynı verileri içerdiğini nasıl sınarım? Bunu doğru bir şekilde test ediyor muyum? Bu benim dördüncü günüm Django'yu öğreniyor, böylece mümkünse en iyi uygulamaları öğrenmek istiyorum. Teşekkürler.

cevap

15

Sizin için iki querysets'i karşılaştırmak üzere oluşturulan assertQuerysetEqual kullanın. Testlerinizde mevcut olması için Django'nun django.test.TestCase alt sınıfına ihtiyacınız olacaktır.

+6

Başar, bu, yararlı olur: AssertionError: [ '< Ürün: Ürün nesnesi> ']! = [<Ürün: Ürün nesnesi>] Gördüğüm tek fark, ilk ürün nesnesinin etrafında tırnak işaretleri bulunmasıdır. Her ikisi de sınıf QuerySet – jz999

+0

Sorunuzu yeni test koduyla güncelleyin. :) – girasquid

+0

Sadece yaptım, teşekkürler – jz999

5

Sadece aynı problemi yaşadım. assertQuerysetEqual'un ikinci argümanı, dizeler olarak beklenen repr() ler listesi olmalıdır.

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

Bkz. Http://stackoverflow.com/a/14189017/678486 (full açıklama bu benim cevabımdır). –

1

bir alternatif, fakat zorunlu olmadan, daha iyi bir yöntem (örneğin, bir görünümde test bağlamı) aşağıdaki gibi görünebilir pytest kullanılarak:

all_the_things = Things.objects.all() 
assert set(list(response.context_data['all_the_things'])) == set(list(all_the_things)) 
Burada Django test paketi ile ilgili bir örnektir

Bu, onu bir listeye, daha sonra başka bir setle doğrudan karşılaştırılabilecek bir kümeye dönüştürür. set'un davranışına dikkat edin, yinelenenleri kaldıracağından tam olarak ne istediğinizi olmayabilir.

1

Varsayılan olarak, assertQuerysetEqual, ilk bağımsız değişkende repr() kullanır; bu nedenle, sorgulama karşılaştırmasında dizelerle ilgili sorunlarınız vardı.

, Bu sorunu gidermek için şunları yapabilirsiniz kullanmayan bir lambda fonksiyonu ile override the transform argument repr():

şimdi benim testleri bu nedenle başarısız olsa
self.assertQuerysetEqual(queryset_1, queryset_2, transform=lambda x: x) 
İlgili konular