Skip to content

Testing

REST framework includes a few helper classes that extend Django's existing test framework, improving support for making API requests.

APIClient

The APIClient class acts as a dummy web browser, allowing you to test your views and interact with your application programmatically. It extends Django's standard Client but specifically targets APIs.

python
from rest_framework.test import APIClient
from django.test import TestCase

class ExampleTestCase(TestCase):
    def setUp(self):
        self.client = APIClient()

    def test_example(self):
        # Issue a GET request.
        response = self.client.get('/api/users/')
        self.assertEqual(response.status_code, 200)

        # Issue a POST request.
        response = self.client.post('/api/users/', {'name': 'new idea'}, format='json')
        self.assertEqual(response.status_code, 201)

By default, .post() and .put() methods encode data as multipart/form-data. Using format='json' sends a JSON-encoded request body.

APITestCase

APITestCase extends Django's standard TestCase, replacing the standard Client with APIClient.

python
from rest_framework.test import APITestCase
from rest_framework import status

class AccountTests(APITestCase):
    def test_create_account(self):
        url = '/account/'
        data = {'name': 'DabApps'}
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data['name'], 'DabApps')

Authentication

When testing authenticated endpoints, you can forcefully authenticate the APIClient.

Forcing Authentication

You can use .force_authenticate() to bypass regular authentication steps:

python
from django.contrib.auth.models import User
from rest_framework.test import APIClient

client = APIClient()
user = User.objects.get(username='admin')

# Force authentication
client.force_authenticate(user=user)
response = client.get('/api/restricted/')
self.assertEqual(response.status_code, 200)

# Clear authentication
client.force_authenticate(user=None)

Credentials

Alternatively, you can include specific headers like an authorization token using .credentials():

python
client = APIClient()
client.credentials(HTTP_AUTHORIZATION='Token ' + token)
response = client.get('/api/restricted/')

APIRequestFactory

If you want to test the view function or class directly, instead of routing through the Django URL dispatcher, you can use APIRequestFactory. It creates mock Request objects.

python
from rest_framework.test import APIRequestFactory
from .views import UserListView

factory = APIRequestFactory()
request = factory.get('/users/')

view = UserListView.as_view()
response = view(request)
self.assertEqual(response.status_code, 200)