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,所以您检查了两次相同的响应。

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和一个测试测试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 回答