marue
marue

Reputation: 5726

Can i access the response context of a view tested without the test client?

I have a function which i call from a unittest. From setting some debug traces i know the function worked like a charm and has all the values correctly prepared for return.

This is what my testcode looks like (see where my ipdb.set_trace() is ):

@override_settings(REGISTRATION_OPEN=True)
def test_confirm_account(self):
    """ view that let's a user confirm account creation and username
        when loggin in with social_auth """    
    request = self.factory.get('')
    request.user = AnonymousUser()
    request.session={}
    request.session.update({self.pipename:{'backend':'facebook',
                                           'kwargs':{'username':'Chuck Norris','response':{'id':1}}}})

    # this is the function of which i need the context:
    response = confirm_account(request)
    self.assertEqual(response.context['keytotest'],'valuetotest')

From what i know from this part of the Django docs, i would be able to access response.context when i have used the testing client. But when i try to access response.context like i did it, i get this:

AttributeError: 'HttpResponse' object has no attribute 'context'

Is there a way to get the special HttpResponse object of the client, without using the client?

Upvotes: 13

Views: 13057

Answers (5)

F.Tamy
F.Tamy

Reputation: 653

The "response.context" is incorrect for new django versions but you can use response.context_data to get the same context that passed to TemplateResponse.

Upvotes: 6

wilcus
wilcus

Reputation: 859

Yes, you can. You have to patch render.

I'm using pytest-django

class Test:
    def context(self, call_args):
        args, kwargs = call_args
        request_mock, template, context = args
        return context

    @patch('myapplication.views.render')
    def test_(self, mock_render, rf):
        request = rf.get('fake-url')
        view(request)
        context = self.context(mock_render.call_args)

        keytotest = 'crch'
        assert keytotest == context['keytotest']

Upvotes: 1

Abdul-Hakeem Shaibu
Abdul-Hakeem Shaibu

Reputation: 11

Though this is an old post, I suppose this tip can be of help. You can look into using TemplateResponse (or SimpleTemplateResponse) which can be substituted for render or render_to_response.

The Django docs has more on this

Upvotes: 1

starenka
starenka

Reputation: 580

context (sic!) can be found in Response class. As you see it says it's HTTPResponse you get back from the view function. This happened because you've called it directly. Call this function via test client and it will be okay.

response = client.get('/fobarbaz/')
response.context

Upvotes: -6

jlovison
jlovison

Reputation: 1136

The RequestFactory does not touch the Django middleware, and as such, you will not generate a context (i.e. no ContextManager middleware).

If you want to test the context, you should use the test client. You can still manipulate the construction of the request in the test client either using mock or simply saving your session ahead of time in the test, such as:

from django.test import Client
c = Client()
session = c.session
session['backend'] = 'facebook'
session['kwargs'] = {'username':'Chuck Norris','response':{'id':1}}
session.save()

Now when you load the view with the test client, you'll be using the session as you set it, and when you use response = c.get('/yourURL/'), you can then reference the response context using response.context as desired.

Upvotes: 12

Related Questions