Search code examples
pythondjangotestcase

Django Testing KeyError When Retrieving Header from Request Object


So I'm trying to confirm the location of a given view during testing. The docs say:

You can also use dictionary syntax on the response object to query the value of any settings in the HTTP headers. For example, you could determine the content type of a response using response['Content-Type'].

However, when I put it to use I'm getting a key error. Help please.

Test:

def test_normal_rewardstore_usage(self):    
    logged_in = self.client.login(username=self.u1.username, password="psst")
    response = self.client.get(reverse('rewards:rewardstore'))
    location = "http://testserver%s" % (reverse('rewards:rewardpage', kwargs={'company':self.r1.company.slug, 'slug':self.r1.slug}))
    self.assertEqual(response.status_code, 200)
    self.assertEqual(response['Location'], location)

Error:

Traceback (most recent call last):
  File "/app/rewards/tests/test_views.py", line 58, in test_normal_rewardstore_usage
    self.assertEqual(response['Location'], location)
  File "/app/.heroku/python/lib/python2.7/site-packages/django/http/response.py", line 189, in __getitem__
    return self._headers[header.lower()][1]
KeyError: 'location'

View:

def RewardStore_Index(request, template='rewards/reward-store.html', page_template='rewards/rewards_page.html'):
    user = User.objects.get(pk=request.user.pk)
    contact = Contact.objects.get(user__pk=request.user.pk, is_active=True)
    if request.user.is_authenticated():
    a = Member.objects.get(pk=request.user.pk)
    a = a.account_verified
    rewards = Reward.objects.filter(country__iso=contact.get_country)
    else:
    a = False
    g = GeoIP()
    c = g.country(request.user)
    c = c['country_code']
    rewards = Reward.objects.filter(country__iso=c)
    context = {
    'targetuser': request.user,
        'rewards': rewards,
        'page_template': page_template,
        'email_authenticated': True if a else False,
    'notifications': NotificationMap.objects.filter(user__pk=request.user.pk, read=False).prefetch_related('notification', 'notification__users')
    }
    if request.is_ajax():
        template = page_template
    return render_to_response(
        template, context, context_instance=RequestContext(request))

Solution

  • The headers made available in the response object will vary depending on the server used (source), so it wouldn't surprise me if the django test runner doesn't send back all the headers that you see in production. Also, Location is generally used with redirecting responses, and you're asserting that you receive a 200 first. Are you sure that you should be expecting a Location header in this circumstance?