#30101: Recommended middleware syntax fails for some testing cases (when not
using
Client)
-------------------------------------+-------------------------------------
Reporter: tdiam | Owner: nobody
Type: Uncategorized | Status: new
Component: Documentation | Version: 2.1
Severity: Normal | Resolution:
Keywords: middleware, unit | Triage Stage:
test, requestfactory, request, | Unreviewed
layering |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by tdiam:
Old 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:
>
> {{{
> #!python
> 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:
>
> {{{
> #!python
> 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:
>
> {{{
> #!python
> 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:
> {{{
> #!python
> 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.
New 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:
{{{
#!python
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:
{{{
#!python
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:
{{{
#!python
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 expected too:
{{{
#!python
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.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/30101#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/063.208f071c253d876e86f53a9671f8b241%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.