Manually get a response from a generic class-based view

I am trying to write a test that checks the HTML returned from the general view of a class. Let's say I have this functional representation that just displays a template:

# views.py from django.shortcuts import render def simple_view(request, template='template.html'): return render(request, template) 

At the same time, during testing, I can simply do:

 # tests.py from django.http import HttpRequest from .views import simple_view request = HttpRequest() response = simple_view(request) 

and then check for response . Now, I would like to convert the above into a view class that inherits from TemplateView:

 # views.py from django.views.generic import TemplateView class SimpleView(TemplateView): template_name = 'template.html' 

Now essentially the same testing method fails:

 # tests.py from django.http import HttpRequest from .views import SimpleView request = HttpRequest() view_func = SimpleView.as_view() response = view_func(request).render() 

leads to

 Traceback (most recent call last): File "tests.py", line 30, in test_home_page_returns_correct_html response = view_func(request).render() File "lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view return self.dispatch(request, *args, **kwargs) File "lib/python2.7/site-packages/django/views/generic/base.py", line 82, in dispatch if request.method.lower() in self.http_method_names: AttributeError: 'NoneType' object has no attribute 'lower' 

I tried setting request.method manually on GET , but this only causes one more error complaining about session not in request .

Is there a way to get a response from a TemplateView with an "empty" request?

+4
source share
2 answers

Thanks dm03513 for the pointers! Indeed, I had to use RequestFactory, but also make sure that request contains an empty session (despite the fact that SessionMiddleware will be specified first):

 # tests.py from django.test import TestCase from django.test.client import RequestFactory class SimpleTest(TestCase): def setUp(self): self.factory = RequestFactory() def test_home_page_returns_correct_html(self): request = self.factory.get('/') request.session = {} view_func = SimpleView.as_view() response = view_func(request) response.render() self.assertIn('<html>', response.content) 
+4
source

You can use the djangos built-in to the test client to accomplish this, instead of directly creating and invoking a view

test client allows you to execute a request through the django url router

response = self.get('/url/to/invoke/simpleview/')

In addition, there are several blogposts that I have found regarding how to test class-based views, one of which is http://tech.novapost.fr/django-unit-test-your-views-en.html

+2
source

All Articles