Django тестирует, как утверждать перенаправление

Со следующим кодом я получаю неправильный результат: 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/')

person Brigitte Maillère    schedule 30.10.2017    source источник
comment
Какой код вы тестируете? Кроме того, название вопроса, похоже, не имеет ничего общего с содержанием вопроса.   -  person Håken Lid    schedule 30.10.2017
comment
Название отредактировано. Извините, было сочетание между публикацией черновиков.   -  person Brigitte Maillère    schedule 31.10.2017
comment
Может ли быть так, что представление в /mes_dossiers/ также перенаправляет на другой URL-адрес?   -  person Håken Lid    schedule 31.10.2017


Ответы (3)


Я нашел больше примеров там:

Django: проверка, была ли страница перенаправлена ​​на желаемый 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)
person Brigitte Maillère    schedule 09.11.2017
comment
Разве django.tests.TestCase.client.get не дает вам объект ответа? - person Işık Kaplan; 03.06.2021

Я добираюсь до этого вопроса через Google, и у меня есть аналогичная проблема с перенаправлением тестирования.

Но мой Django - это версия 2.2, и в принятом ответе указана версия 1.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

person Kim Stacks    schedule 04.06.2020

Для проверки редиректов следует использовать тестовый клиент вместо RequestFactory.

API для RequestFactory — это немного ограниченное подмножество тестового клиентского API:

  • Он имеет доступ только к HTTP-методам get(), post(), put(), delete(), head(), options() и trace().

  • Эти методы принимают все те же аргументы, кроме следующих. Поскольку это всего лишь фабрика по производству запросов, вам решать, как обрабатывать ответ.

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)
person Håken Lid    schedule 30.10.2017