Как TDD может применяться к базовым представлениям на основе класса Django? - PullRequest
24 голосов
/ 22 декабря 2011

Поскольку основанные на классах общие представления в Django требуют некоторой работы со структурой, мне очень трудно работать с ними в стиле TDD. Теперь я использую TestClient для доступа к представлению из макетированного стека http, но я бы предпочел правильно протестировать определенные методы (например, переопределения get_object и get_queryset) перед «функциональным» тестированием с TestClient.

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

Ответы [ 3 ]

16 голосов
/ 22 декабря 2011

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

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

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

8 голосов
/ 23 августа 2013

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

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)

Я бы также рекомендовалпросматривая документацию, упомянутую Филиппом в его ответе .

5 голосов
/ 29 ноября 2014

Я искал простое решение для той же проблемы сегодня и нашел это действительно замечательное сообщение в блоге от Бенуа Брайона (спасибо!).

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

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...