Search code examples
djangounit-testingmiddleware

Django unit testing middleware error


This is my middleware -

class HeadersControlMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)

        response['Cache-Control'] = "no-cache"
        # Code to be executed for each request/response after
        # the view is called.

        return response

and this is my unit test -

class TestHeadersControlMiddleware(MyAPITestCase):

    def dummy_middleware(self):
        response = Response()
        response.status_code = 200
        response.json = {"key1": "value1"}

        return response

    def test_cache_control_header_is_added(self):
        self.middleware = HeadersControlMiddleware(self.dummy_middleware())
        self.request = RequestFactory()
        self.request.META = {
            "REQUEST_METHOD": "POST",
            "HTTP_APP_VERSION": "1.0.0",
            "HTTP_USER_AGENT": "AUTOMATED TEST"
        }
        self.request.path = '/testURL/'
        self.request.session = {}

        response = self.middleware(self.request)

        print(str(response['Cache-Control']))

When running the test I'm getting the following error:

File ".../tests/test_headers_control_middleware.py", line 56, in test_cache_control_header_is_added
response = self.middleware(self.request)
File "..../api/headers_control_middleware.py", line 10, in __call__
response = self.get_response(request)
TypeError: 'Response' object is not callable

Any idea?

EDIT - Apparently, I returned 'Response' in 'dummy_middleware' instead of 'response' (thanks to @szymon for noticing). So I fixed that and updated the current error and question.


Solution

  • Your dummy_middleware method should take request as an argument. I would move it outside of the test case so you don't have to worry about self.

    def dummy_middleware(request):
        response = Response()
        response.status_code = 200
        response.json = {"key1": "value1"}
        return response
    

    Then you should initialise the middleware with dummy_middleware, not dummy_middleware() as you currently have.

    self.middleware = HeadersControlMiddleware(dummy_middleware)
    ...
    response = self.middleware(self.request)