Django Testing - access session in RequestFactory
Asked Answered
P

4

6

I am using RequestFactory in a Django test, and I can't find the right way to access the session variable, and I'm getting the following error when I try self.factory._session["zip_id"] or self.factory.session["zip_id"].

======================================================================
ERROR: test_middleware (dj_geo.tests.IPToZipMiddleWareTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "c:\dj_site_test\dj_geo\tests.py", line 36, in test_middleware
    assert self.factory._session["zip_id"] != None
AttributeError: 'RequestFactory' object has no attribute '_session'

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



@override_settings(MIDDLEWARE_CLASSES=(
    'dj_geo.middleware.IPToZipMiddleWare'
))
class IPToZipMiddleWareTest(TestCase):

    def test_middleware(self):
        Zipcode.syncdb()
        assert Zipcode.objects.all().count() > 0

        self.factory = RequestFactory()
        self.request = self.factory.get('/', {}, **{'REMOTE_ADDR':'108.31.178.99'})
        assert self.factory._session["zip_id"] != None
        assert self.factory._session["zip_id"] != ""
Peccable answered 9/10, 2016 at 18:52 Comment(0)
U
12

Save session information to request using your middleware:

from django.contrib.sessions.middleware import SessionMiddleware

request = RequestFactory().get('/')
middleware = SessionMiddleware()
middleware.process_request(request)
request.session.save()
Undying answered 5/4, 2019 at 8:7 Comment(1)
I started getting TypeError: __init__() missing 1 required positional argument: 'get_response' on Django 4.0 with this solution. I solved it by middleware = SessionMiddleware(lambda x: x) Although I don't know, if it is really correct solution.Dewitt
T
6

You can use SessionMiddleware, indeed. However, its constructor requires a callback, as any middleware. The callback is provided by Django run-time in order to keep processing the middleware chain or to execute the view as soon as the chain reaches the end. Since we are not interested in view execution, for this case, you may do the following:

from django.contrib.sessions.middleware import SessionMiddleware

request = RequestFactory().get('/')
middleware = SessionMiddleware(lambda x: None)
middleware.process_request(request)
request.session.save()

By processing the request, session field will be added to it and you can keep going with your testing.

Tracitracie answered 14/10, 2022 at 12:58 Comment(0)
M
0

You may need to use the SessionMiddleware to process your request, then save it to store the session. You can refer to this article. I also don't think it's a good idea to access the protected attributes of the factory directly, like this self.factory._session["zip_id"], it will just get you into more problems. Goodluck!

Miyamoto answered 4/1, 2019 at 15:40 Comment(0)
F
-1

You need to use Client for this instead of RequestFactory

self.factory = Client()
Fourfold answered 10/10, 2016 at 7:25 Comment(1)
This doesn't work for me. Still getting AttributeError: 'TemplateResponse' object has no attribute 'session'.Dewitt

© 2022 - 2024 — McMap. All rights reserved.