【问题标题】:Django testing how to assert RedirectDjango测试如何断言重定向
【发布时间】:2018-04-11 17:28:18
【问题描述】:

使用以下代码,我得到了错误的结果:nose.proxy.AssertionError: 302 != 200 : 无法检索重定向页面“/mes_dossiers/”:响应代码为 302(预期为 200)

我的代码有什么问题?

#test.py
from django.test import TestCase, RequestFactory, Client
from ..models import *
from ..views import *
from django.core.management import call_command

class Cas(TestCase):

    def setUp(self):
        call_command('loaddata', 'fixture_users.json', verbosity=1)
        call_command('loaddata', 'xxxxx_tests_xxxx.yaml', 
        verbosity=1)

    def test_dossier_duplicate(self) :
        request = self.factory.get('/dossier/3/copier/', follow = True)
        request.user = User.objects.get(id=3)
        pk = 3
        response = dossier_duplicate(request, pk)
        response.client = Client()
        self.assertRedirects(response,'/mes_dossiers/',status_code=302, 
        target_status_code=200)

#urls.py
urlpatterns = [    
url(r'^dossier/(?P<pk>[0-9]+)/copier/$',views.dossier_duplicate),  

]

#views.py
@login_required(login_url="/accounts/login/")
def dossier_duplicate(request, pk):

    dossier = get_object_or_404(Dossier, pk=pk)
    groupe = dossier.createdBy.groups.all()[0].name

    if not in_group(request.user, groupe) :
        return HttpResponseForbidden('Vous ne pouvez pas accéder à ce 
        dossier')

    else :

        #code to duplicate the "dossier" instance and child contents
        #
        #

        return redirect('/mes_dossiers/')

【问题讨论】:

  • 你测试的代码是什么?此外,问题的标题似乎与问题的内容无关。
  • 标题已编辑。抱歉,发布草稿之间存在混合。
  • 会不会是/mes_dossiers/的视图也重定向到另一个url?

标签: django testing django-unittest


【解决方案1】:

我在那里找到了更多示例:

Django : Testing if the page has redirected to the desired url

https://docs.djangoproject.com/en/3.0/topics/testing/tools/#django.test.SimpleTestCase.assertRedirects

这很有效:

class Cas(TestCase):

    def setUp(self):
        call_command('loaddata', 'fixture_users.json', verbosity=1)
        call_command('loaddata', 'xxx_tests_xxxx.yaml', 
        verbosity=1)

    def test_dossier_duplicate(self) :
        request = self.client.get('/dossier/3/copier/', follow = True)
        request.user = User.objects.get(id=3)
        pk = 3
        response = dossier_duplicate(request, pk)
        response.client = Client()
        response.client.login(username='xxxx', password='xxxxx')

        self.assertRedirects(response, '/mes_dossiers/', status_code=302, 
        target_status_code=200, fetch_redirect_response=True)

【讨论】:

  • django.tests.TestCase.client.get 不给你一个响应对象吗?
【解决方案2】:

我通过谷歌找到了这个问题,我在测试重定向时遇到了类似的问题。

但我的 Django 是 v2.2,并且接受的答案引用了不再支持的 v1.7

然后我在谷歌上搜索了更多内容,并在https://docs.djangoproject.com/en/2.2/topics/testing/tools/#django.test.SimpleTestCase.settings找到了这个代码块

from django.test import TestCase

class LoginTestCase(TestCase):

    def test_login(self):

        # First check for the default behavior
        response = self.client.get('/sekrit/')
        self.assertRedirects(response, '/accounts/login/?next=/sekrit/')

我为自己的使用进行了修改,效果很好。

对于 OP 案例,我认为 如果 OP 使用 2.2

,这就是我认为应该工作的方式
def test_dossier_duplicate(self) :
    response = self.client.get('/dossier/3/copier/')
    self.assertRedirects(response, '/mes_dossiers/')

我将把它留在这里。万一以后的读者有类似的问题,但对于 Django v2.2 有类似的问题

【讨论】:

    【解决方案3】:

    要测试重定向,您应该使用测试客户端而不是 RequestFactory。

    RequestFactory 的 API 是 测试客户端 API:

    • 它只能访问 HTTP 方法 get()、post()、put()、delete(), 头(),选项()和跟踪()。

    • 这些方法都接受相同的 参数,除了以下。因为这只是一个工厂 产生请求,由你来处理响应。

    https://docs.djangoproject.com/en/1.11/topics/testing/advanced/#the-request-factory

    尝试将self.factory.get 更改为self.client.get

        response = self.client.get('/dossier/3/copier/', follow = True)
    

    【讨论】:

      猜你喜欢
      • 2023-04-02
      • 2020-02-11
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 2014-07-14
      • 1970-01-01
      相关资源
      最近更新 更多