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.
Patch for documentation