#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.

Reply via email to