djangodjango-rest-frameworkdjango-testingdjango-tests

Django Middleware does not modify request in tests


I am trying to create test class for my custom middleware. The project is using Django REST framework. Middleware class works fine when server is running, but when I run test it behaves not quite as I would expect it to do. Maybe I misunderstood something, as I am quite new to testing in Django.

my_middleware.py:

class FX:
    a = False
    b = None
    c = ''

    def __init__(self) -> None:
        pass

    def __str__(self):
        return 'fx ok'

class MyMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        request.fx = FX()
        response = self.get_response(request)
        print('done')
        return response

views.py:

class TestView(APIView):
    def get(self, request, format=None):
        print('View ok')
        print('FX: ', request.fx)
        return Response({'result':'ok'})

tests.py:

class TestMyMiddleware(APITestCase):
    @classmethod
    def setUpTestData(cls):
        pass

    def setUp(self):
        pass

    def test_fx(self):
        response = self.client.get(reverse('TestView'), content_type="application/json")
        request = response.request
        self.assertTrue(hasattr(request, 'fx'))

The code above actually runs the middleware. It prints "done" form the middleware call, then prints 'View ok' and also prints FX instance. However request.fx is not available in the test_fx method, thus giving assertion failure:

self.assertTrue(hasattr(request, 'fx'))
AssertionError: False is not true

Any idea what I might be doing wrong?


Solution

  • You need to access the request object from the response with response.wsgi_request instead of response.request.

    class TestMyMiddleware(APITestCase):
        @classmethod
        def setUpTestData(cls):
            pass
    
        def setUp(self):
            pass
    
        def test_fx(self):
            response = self.client.get(reverse('TestView'), content_type="application/json")
            request = response.wsgi_request
            self.assertTrue(hasattr(request, 'fx'))