Django 测试如何断言重定向
Django testing how to assert Redirect
使用以下代码我得到了错误的结果: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/')
要测试重定向,您应该使用测试客户端而不是 RequestFactory。
The API for the RequestFactory is a slightly restricted subset of the
test client API:
It only has access to the HTTP methods get(), post(), put(), delete(),
head(), options(), and trace().
These methods accept all the same
arguments except for follows. Since this is just a factory for
producing requests, it’s up to you to handle the response.
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)
我在那里找到了更多示例:
Django : Testing if the page has redirected to the desired url
这有效:
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)
我通过 google 遇到了这个问题,我在测试重定向时遇到了类似的问题。
但我的 Django 是 v2.2,接受的答案引用了不再支持的 v1.7
然后我 google 又在 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
使用以下代码我得到了错误的结果: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/')
要测试重定向,您应该使用测试客户端而不是 RequestFactory。
The API for the RequestFactory is a slightly restricted subset of the test client API:
It only has access to the HTTP methods get(), post(), put(), delete(), head(), options(), and trace().
These methods accept all the same arguments except for follows. Since this is just a factory for producing requests, it’s up to you to handle the response.
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)
我在那里找到了更多示例:
Django : Testing if the page has redirected to the desired url
这有效:
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)
我通过 google 遇到了这个问题,我在测试重定向时遇到了类似的问题。
但我的 Django 是 v2.2,接受的答案引用了不再支持的 v1.7
然后我 google 又在 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