58

I am trying to decide whether I should use Django's Client or RequestFactory to test my views.

I am creating my server using DjangoRESTFramework and it's really simple, so far:

class SimpleModelList(generics.ListCreateAPIView):
    """
    Retrieve list of all route_areas or create a new one.
    """
    queryset = SimpleModel.objects.all()
    serializer_class = SimpleModelSerializer
    filter_backends = (IsOwnerFilterBackend,)

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

What are the differences between testing with Django's Client and RequestFactory and which approach is more suited for testing a REST server (if there is any difference besides liking one better)?

Should I create tests with both so as to provide a better coverage for my system?

t.pimentel
  • 1,225
  • 2
  • 16
  • 24

2 Answers2

94

RequestFactory and Client have some very different use-cases. To put it in a single sentence: RequestFactory returns a request, while Client returns a response.

The RequestFactory does what it says - it's a factory to create request objects. Nothing more, nothing less.

The Client is used to fake a complete request-response cycle. It will create a request object, which it then passes through a WSGI handler. This handler resolves the url, calls the appropriate middleware, and runs the view. It then returns the response object. It has the added benefit that it gathers a lot of extra data on the response object that is extremely useful for testing.

The RequestFactory doesn't actually touch any of your code, but the request object can be used to test parts of your code that require a valid request. The Client runs your views, so in order to test your views, you need to use the Client and inspect the response. Be sure to check out the documentation on the Client.

knbk
  • 46,344
  • 6
  • 103
  • 109
  • 1
    Thank you for this answer. Could you give me an example where a factory would be more appropriate to be used for testing? – t.pimentel Jun 23 '15 at 11:33
  • 8
    If you were to create something similar to the built-in [`AuthenticationForm`](https://docs.djangoproject.com/en/1.8/topics/auth/default/#django.contrib.auth.forms.AuthenticationForm), which takes a `request` object as its first argument, you'd use the `RequestFactory` to test it. – knbk Jun 23 '15 at 11:43
  • 8
    I don't think it's strictly necessary to use a `Client` to test views. I've seen code that creates a `request` with a `RequestFactory` and then calls `SomeView.as_view()(request)` to get the response. But I came here because I wasn't sure that's the best way to do it. Folks in another issue say `Client` is more for integration testing: http://stackoverflow.com/questions/5777447/test-django-views-that-require-login-using-requestfactory?rq=1 – Andy Feb 17 '17 at 02:25
  • 8
    You'd use the the Request Factory if you were unit testing the View class, but you'd use the Client if you wanted to test the entire request/response cycle, for example. – aphenine Sep 08 '17 at 09:57
1

When using Django REST framework request factory would be helpfull to test the permissions.

EX:

Class TestPermission(TestCase):
  
    def test_admin_permisiion(self):
        admin_user = User.objects.create(email='admin@gmail.com',password='admin997',is_staff=True)
        factory = RequestFactory()
        request = factory.get('/')
        request.user = admin_user
        permission = IsAdminUser()
        has_permission = permission.has_permission(request, None)
        self.assertTrue(has_permission)

what we have done hear is we created a admin user by setting is_staff=True , then we created a request and assigned the admin as user of the request. request factory helps us do so. then we checked the IsAdminUser() permission from DRF against the request. the test will pass .

Client is to be used when you need to test the response returned by an Api.