[Fixed]-Django RequestFactory loses url kwargs

27👍

EDIT 2020-03-07: As gain I more experience in testing, I updated my answer to remove confusion around functional testing and I added some advises.

There are two aspects to your answer.

Quick answer: how to put the kwargs in the view? You need to change your code to this:

def test_different_kwargs():
    kwargs={'some_kwarg': '12345'}
    url = reverse('bots:some_view', kwargs=kwargs)
    c = Client()
    response = c.get(url)
    print('\n\nResponse for TestClient: ', response.content.decode())

    rf = RequestFactory()
    request = rf.get(url)
    response = SomeView.as_view()(request, **kwargs)
    print('\n\nResponse for RequestFactory: ', response.content.decode())

Long answer:
Then the difference between RequestFactory and Client:
It has been developed a bit here: Django test RequestFactory vs Client
but I would like to complete it a bit.

In terms of functionality Client handle the whole stack used to process the response including middlewares and url resolutions (url matching and parameters extraction). On the other side RequestFactory, just build a request object, leaving the responsibility to the user to add the proper attributes and to call the appropriate view functions or view methods.

Hence the call to ClassView.as_view()(request, *args, **kwargs) in the second case.

In terms of testing, Client is focused on integration testing (you will test that all the different parts fit together: middlewares, class-based/function view, template, templatetags), it’s the end-to-end mechanism that you are testing here.

Client -> { UrlResolver -> Middleware -> View -> Middlewares -> TemplateResponse } -> Tests

Using RequestFactory you can focus on testing smaller parts, a class-based view method, a function view, a middleware method etc. In that sense RequestFactory is more related to unit testing.

See Request Factory Reference

If you are interest in unit tests and mocking methods, there is not much literature on this but you can look at this article (Testing Django Views in Isolation)[https://matthewdaly.co.uk/blog/2015/08/02/testing-django-views-in-isolation/].

In the end it all depends on how much you time can focus on testing. Integration/Functional/Unit testings have different advantages and drawbacks.

Advises (may be biased): If you develop a website, I advise the following:

  • focus on integration testing by testing routes and their expected behaviors ;
  • add unit/integration tests for your business logic (models in Django) ;

Unit testing parts using RequestFactory will take you more time and won’t bring much benefits over using the Client API.
Using Client API you will be closer to how your website will be used and how it will behave.

Leave a comment