Подтвердить что ты не робот

Как TDD может быть применен к Generic Views на основе Django?

Поскольку класс Generic Views в Django включает некоторую работу в рамках структуры, мне очень сложно работать с ними в стиле TDD. Теперь я использую TestClient для доступа к представлению из http mocked stack, но я бы предпочел правильно убрать определенные методы (переопределения get_object и get_queryset) перед "функциональным" тестированием с помощью TestClient.

Есть ли (быстрый) способ получить правильный экземпляр ClassView для выполнения unit test на нем?

4b9b3361

Ответ 1

Как правило, это будет включать создание запроса через RequestFactory и создание экземпляра класса представления с аргументами ключевого слова. Впоследствии вы можете вызвать любой из методов представления и оценить результат, передав все необходимые аргументы.

Я бы рекомендовал вам просмотреть базовый класс View, в частности __init__., as_view и dispatch. Они имеют решающее значение для понимания того, как среда взаимодействует с объектами представления.

Самый важный бит, чтобы заметить, что методы просмотра ожидаются, будут вызваны во время процесса запроса-ответа, поэтому им можно будет полагаться на self.request, self.args и self.kwargs, чтобы присутствовать, re, поэтому убедитесь, что у вас это покрыто.

Ответ 2

Не уверен, что это именно то, что вы ищете, но это пример того, как я пытаюсь unit test мои представления (непроверенный код ниже):

import unittest
from django.core.urlresolvers import reverse
from django.test.client import RequestFactory
from ..views import MyClassBasedView

class MyClassBasedViewTestCase(unittest.TestCase):

    def setUp(self):
        self.factory = RequestFactory()

    def test_list_view(self):
        request = self.factory.get(reverse('your_url'))
        # additional params can go after request
        response = MyClassBasedView.as_view()(request)
        self.assertEqual(response.status_code, 200)

Я также рекомендую посмотреть документацию, о которой Филип сказал в его ответ.

Ответ 3

Я искал простое решение для той же проблемы сегодня и нашел этот действительно отличный блог-пост от Benoît Bryon (спасибо!).

Он предложил следующую функцию:

def setup_view(view, request, *args, **kwargs):
    """Mimic as_view() returned callable, but returns view instance.

    args and kwargs are the same you would pass to ``reverse()``

    """
    view.request = request
    view.args = args
    view.kwargs = kwargs
    return view

Пример

Я хотел протестировать следующий CBV:

class CreateList(CreateView):
    model = Item
    form_class = NewListForm
    template_name = 'lists/home_page.html'

    def form_valid(self, form):
        list_ = form.save(owner=self.request.user)
        return redirect(list_)

Необходимые тесты для аргументов метода form.save и для аргументов redirect, которые должны быть возвратным значением первого. Эти тесты будут выглядеть примерно так:

    class CreateListTest(unittest.TestCase):

        def setUp(self):
            self.request = HttpRequest()
            self.request.user = Mock()
            self.form = Mock()
            self.view = setup_view(views.CreateList(), self.request)

        def test_form_dot_save_called_with_user(self):
            self.view.form_valid(self.form)
            self.form.save.assert_called_once_with(owner=self.request.user)

        @patch('lists.views.redirect')
        def test_redirect(self, mock_redirect):
            self.view.form_valid(self.form)
            mock_redirect.assert_called_once_with(self.form.save.return_value)