5

そのため、DeleteView では、GET 要求は確認ページを返します。また、 以外のフィールドを持たない単純な POST 要求は、csrf_token実際に DeleteView を取得してオブジェクトを削除します。これにより、ユーザーは にリダイレクトされますsuccess_url

この機能をテストするにはどうすればよいですか? 私のmyclass_confirm_delete.htmlファイルには、基本的に次のものがあります。

<form action="{% url 'remove_myclass' object.id %}" method="post">
{% csrf_token %}
    <p>Are you sure you want to remove {{ object.name }}?</p>
    <input type="submit" value="Yes" class="btn btn-primary" />
</form>

{% url 'remove_myclass' object.id %}、まったく同じページの URL です。それは私のブラウザで動作します。[はい] をクリックすると、成功ページにリダイレクトされ、myclassオブジェクトがデータベースから削除されます。

今、単体テストでこれを自動的にテストしようとしています。基本的にやってみる

response = self.client.get(reverse('remove_myclass', args=(myobject.id,)), follow=True)
self.assertContains(response, 'Are you sure you want to remove') # THIS PART WORKS
self.client.post(reverse('remove_myclass', args=(myobject.id,)), follow=True)
self.assertRedirects(response, reverse('myclass_removed'), status_code=302) # FAILS; status code is 200

を試してみるとprint response、GET リクエストを使用したときとまったく同じ応答が得られます。

単体テスト中は、POST リクエストでどのようなデータを送信しようとしても、GET リクエストとして扱われるようです...

私のクラスベースのビュー:

class MyclassDelete(DeleteView):
    model = myclass
    success_url = '/myclass-removed/'

何か案は?

4

1 に答える 1

11

postええ、これはリクエストをに割り当てるのを忘れているためですresponse。同じレスポンスを 2 回チェックしています。

response = self.client.get(reverse('remove_myclass', args=(myobject.id,)), follow=True)
self.assertContains(response, 'Are you sure you want to remove') # THIS PART WORKS

post_response = self.client.post(reverse('remove_myclass', args=(myobject.id,)), follow=True)
self.assertRedirects(post_response, reverse('myclass_removed'), status_code=302)

これでうまくいくはずです。

また、ヒントとして、ユニット テストごとに複数回アサートしようとすることは、ユニット テストの際に悪い習慣と見なされます。GET代わりに、1 つのテストで がテストされ、オンのテストで がテストされるように分割してみてくださいPOST

from django.test import TestCase

class TestDifferentRequestMethods(TestCase):

    def test_my_get_request(self):
        response = self.client.get(reverse('remove_myclass', args=(myobject.id,)), follow=True)
        self.assertContains(response, 'Are you sure you want to remove') # THIS PART WORKS

    def test_my_post_request(self):
        post_response = self.client.post(reverse('remove_myclass', args=(myobject.id,)), follow=True)
        self.assertRedirects(post_response, reverse('myclass_removed'), status_code=302)

これにより、デバッグが容易になり、このようなトラブルに遭遇したときに救われることがあります!

UPDATEは、テストを網羅する適切なクラスを完成させていないことに気付きました。

于 2013-04-15T07:45:08.453 に答える