私は私の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.assertQuerysetEqua
ではなくself.assertListEqual
lを使用しています。残念ながらこれはまだ機能せず、ターミナルには次のように表示されます:['<Product: Product object>'] != [<Product: Product object>]
assertListEqual
レイズ:'QuerySet' object has no attribute 'difference'
およびassertEqual
も機能しませんが、self.assertSetEqual(response.context['product_list'][0], merchant.products.all()[0])
はパスします。
これは、同じモデルインスタンスが含まれていても、QuerySetは異なるオブジェクトであるためと考えられます。
2つのクエリセットに同じデータが含まれていることをテストするにはどうすればよいですか?私はこれを正しくテストしていますか?これは私の4日目の学習ですDjangoですから、できればベストプラクティスを知りたいと思います。ありがとうございます。
2つのクエリセットを比較するために作成された assertQuerysetEqual を使用します。テストで使用できるようにするには、DjangoのDjango.test.TestCase
をサブクラス化する必要があります。
デフォルトでは、assertQuerysetEqual
は最初の引数にrepr()
を使用します。これが、クエリセットの比較で文字列に問題があった理由です。
これを回避するには、 transform
引数を上書きするrepr()
を使用しないlambda
関数で上書きします。
self.assertQuerysetEqual(queryset_1, queryset_2, transform=lambda x: x)
私は同じ問題を抱えていました。 assertQuerysetEqual
の2番目の引数は、文字列として予期されるrepr()のリストである必要があります。 Djangoテストスイートの例です:
self.assertQuerysetEqual(c1.tags.all(), ["<Tag: t1>", "<Tag: t2>"], ordered=False)
_self.assertQuerysetEqual
_呼び出し内のクエリセットの各エントリをmap
からrepr()
を使用してこの問題を解決しました。
_self.assertQuerysetEqual(queryset_1, map(repr, queryset_2))
_
Pytestを使用する場合、別の(ただし、必ずしも優れているとは限りません)メソッドは次のようになります(たとえば、ビューのコンテキストをテストします)。
all_the_things = Things.objects.all()
assert set(list(response.context_data['all_the_things'])) == set(list(all_the_things))
これにより、リスト、次にセットに変換され、別のセットと直接比較できます。ただし、set
の動作には注意してください。重複が削除されるため、意図したとおりにならない場合があります。
self.assertCountEqual(queryset1, queryset2)
を使用しても問題が解決することがわかりました。