Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

KeyError: 'HTTP_HOST' when running django tests

I am new to unit testing so I have no idea what I am doing wrong. I use python2.7 with Django1.8

When I run

python manage.py test myapp --keepdb

I get

======================================================================
ERROR: test_view_content (myproject.news.tests.test_views.EntryTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/zoli/projects/project_dict/myproject/news/tests/test_views.py", line 27, in test_view_content
    response = client.get(reverse('news_list', kwargs={'page': 1}))
  File "/home/zoli/.virtualenvs/project_dict/local/lib/python2.7/site-packages/django/test/client.py", line 500, in get
    **extra)
  File "/home/zoli/.virtualenvs/project_dict/local/lib/python2.7/site-packages/django/test/client.py", line 303, in get
    return self.generic('GET', path, secure=secure, **r)
  File "/home/zoli/.virtualenvs/project_dict/local/lib/python2.7/site-packages/django/test/client.py", line 379, in generic
    return self.request(**r)
  File "/home/zoli/.virtualenvs/project_dict/local/lib/python2.7/site-packages/django/test/client.py", line 466, in request
    six.reraise(*exc_info)
  File "/home/zoli/.virtualenvs/project_dict/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 108, in get_response
    response = middleware_method(request)
  File "/home/zoli/projects/project_dict/myproject/middleware/multihostname.py", line 18, in process_request
    host = request.META['HTTP_HOST'].split(':')[0]
KeyError: u'HTTP_HOST'

----------------------------------------------------------------------

My tests look like

from django.test import TestCase, Client
from django.contrib.sites.models import Site
from myproject.news.models import Entry
from myproject.people.models import User
from django.core.urlresolvers import reverse


class EntryTestCase(TestCase):
    def setUp(self):
        user1 = User.objects.create(username='zoli')
        site1 = Site.objects.create(domain='mysite.sk', name='mysite')
        entry = Entry(author=user1, title='Titulok', text='Toto je obsah')
        entry.save()
        entry.sites.add(site1)
        entry.save()

    def test_view_content(self):
        client = Client()

        response = client.get(reverse('news_list', kwargs={'page': 1})) # This is raising and error
        print response.content

When I visit /novinky/strana/1/ everything goes fine so I suppose the error is in the test. If you need any other code I'll paste it here.

like image 506
Zoli Avatar asked Jan 19 '16 12:01

Zoli


People also ask

Why is Django throwing hostname errors when running a package?

Since '/home/scheduler/run/gunicorn.sock' is not a valid host name, the error is thrown - again before any comparison is made with the ALLOWED_HOSTS setting. So, you’ve got something in your stack before Django sees this request that is replacing the HTTP_HOST header with that value.

What testing framework should I use with Django?

You can also use any other Python test framework; Django provides an API and tools for that kind of integration. They are described in the Using different testing frameworks section of Advanced testing topics.

How do I run a test in Django?

With Django’s test-execution framework and assorted utilities, you can simulate requests, insert test data, inspect your application’s output and generally verify your code is doing what it should be doing. The preferred way to write tests in Django is using the unittest module built-in to the Python standard library.

What is a Python keyerror?

What a Python KeyError Usually Means A Python KeyError exception is what is raised when you try to access a key that isn’t in a dictionary (dict). Python’s official documentation says that the KeyError is raised when a mapping key is accessed and isn’t found in the mapping. A mapping is a data structure that maps one set of values to another.


1 Answers

The HTTP_HOST header is not set by the Django test client by default. Your multihost middleware assumes that the header is always present, so you get a KeyError when the tests run.

You may want to change your multihostname middleware so that it doesn't cause an error when the header is not in the request.

if 'HTTP_HOST' in request.META:
    host = request.META['HTTP_HOST'].split(':')[0]
    ...
else:
    # do something else

Or maybe have a default host:

host = request.META.get('HTTP_HOST', 'defaulthost.com').split(':')[0]

If you want to test the effect of different headers, you can include the header when you make a request:

client = Client()
# Make a request, setting the header manually
client.get('/my_url', HTTP_HOST='example.com')

Or you can set up the test client to include a header in all requests:

client = Client(HTTP_HOST='example.com')
# The header will be set for both of the following requests
client.get('/my_url/')
client.get('/my_second_url/')

See the docs on making requests for more info.

like image 138
Alasdair Avatar answered Sep 19 '22 11:09

Alasdair