Opened 6 years ago

Last modified 6 years ago

#30101 closed Cleanup/optimization

Recommended middleware syntax fails for some testing cases (when not using Client) — at Initial Version

Reported by: Theodore Diamantidis Owned by: nobody
Component: Documentation Version: 2.1
Severity: Normal Keywords: middleware, unit test, requestfactory, request, layering
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

It is common for developers to prefer RequestFactory over Client in unit testing, or any similar module that mocks requests without processing the URLs or applying the enabled middleware. So, when a unit test needs to test a view while using a middleware, the easiest way to do so is:

from django.test import RequestFactory

from .views import MyView
from .middleware import MyMiddleware

request = RequestFactory().get('/')
view = MyMiddleware(MyView)
response = view(request)

Also, it may be needed to test views that accept arguments (e.g. captured URL parameters), which would probably look like this:

request = RequestFactory().get('/articles/4/')
response = MyView(request, pk=4)

The problem arises when we both use test views that accept parameters and a custom middleware. The current documentation offers examples for writing such a middleware:

def MyMiddleware(get_response):
    # One-time configuration and initialization.

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

        response = get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response

    return middleware

Given the above tests, one would expect this one to work as well as expected:

request = RequestFactory().get('/articles/4/')
view = MyMiddleware(MyView)
response = view(request, pk=4)

However this is not the case, since the middleware function expects only a single positional argument and not the keyword argument pk, thus raising a TypeError.

The attached files recommend a more flexible (albeit less simple) syntax and data flow for custom middleware that would prevent inexperienced developers from getting stuck here.

Change History (1)

by Theodore Diamantidis, 6 years ago

Patch for documentation

Note: See TracTickets for help on using tickets.
Back to Top