2013-07-16 17 views
13

私はDjangoビューをテストしようとしています。このビューには、テンプレートにクエリセットを渡します。Djangoのクエリセットはどのようにテストするのですか?

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

EDIT 私はself.assertQuerysetEqual代わりのself.assertListEqualを使用しています。残念ながら、これはまだ動作しませんし、端末のディスプレイこの: ['<Product: Product object>'] != [<Product: Product object>]


assertListEqualが提起:「クエリセット」オブジェクトがself.assertSetEqual(response.context['product_list'][0], merchant.products.all()[0])が通過んが assertEqualは、いずれかの動作しません何の属性の違い」を持っていません。

これは、同じモデルインスタンスが含まれていても、QuerySetsが異なるオブジェクトであると考えられます。

2つのクエリセットに同じデータが含まれていることをテストするにはどうすればよいですか?私はこれをすべて正しくテストしていますか?可能な場合、私はベストプラクティスを知りたいので、これはDjangoを学ぶ私の4日目です。ありがとう。

答えて

15

assertQuerysetEqualを使用してください。これは、2つのクエリーセットを比較するために作成されています。 Djangoのdjango.test.TestCaseをサブクラス化して、テストで利用できるようにする必要があります。

+6

恐ろしいが、これが今の私のテストはこのために失敗したものの、有用である: てAssertionError:[ '<製品:製品オブジェクト> ']!= [] 最初の製品オブジェクトの周りに引用符があることがわかります。それらは両方ともクラスQuerySet – jz999

+0

です。あなたの質問を新しいテストコードで更新してください。 :) – girasquid

+0

ちょうど、ありがとう – jz999

5

私はちょうど同じ問題を抱えていました。 assertQuerysetEqualの2番目の引数は、予想される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)) 
をここでDjangoのテストスイートの例であります

これはリストに変換し、次に別のセットと直接比較可能なセットに変換します。 setの動作には注意してください。重複を取り除くので、正確には望んでいない可能性があります。

1

デフォルトでは、assertQuerysetEqualは最初の引数にrepr()を使用しています。そのため、クエリーセット比較の文字列に問題があったのです。これを回避するには

、あなたはrepr()使用しないlambda機能付きoverride the transform argumentことができます。

self.assertQuerysetEqual(queryset_1, queryset_2, transform=lambda x: x) 
関連する問題