I'm writing tests for my API. Now i want to test post method.
Here's my views.py
:
class TaskViewSet(viewsets.ModelViewSet):
queryset = Task.objects.all()
serializer_class = serializers.TaskSerializer
authentication_classes = (BasicAuthentication,)
permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser)
Here's my tests.py
:
class UserFactory(DjangoModelFactory):
class Meta:
model = User
username = 'dima'
password = 'moonmvm2k14'
email = '[email protected]'
is_superuser = True
is_active = True
is_staff = True
class TaskFactory(DjangoModelFactory):
class Meta:
model = Task
title = "TASK N1"
description = "smth"
person = factory.SubFactory(UserFactory)
deadline = date.today()
class ViewTest(APITestCase):
def setUp(self):
self.task = TaskFactory()
self.username = 'myuser'
self.password = 'test'
self.email = '[email protected]'
self.admin = User.objects.create_superuser(self.username, self.password, self.email)
self.client = APIClient()
self.client.login(username=self.admin.username, password=self.admin.password)
def test_post_task(self):
url = '/task-list/'
json_tasks = serializers.TaskSerializer(self.task)
data = json_tasks.data
response = self.client.post(url, data)
tasks_count = Task.objects.count()
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(tasks_count, 2)
But when i try to test it i see this error:
AssertionError: 401 != 201
I don't know why my test fails with Not Authorized Status Code.
So, what's the problem and how can I solve it?
The issue origins from the way you simulate login in the test case.
You are using the login()
method of the APIClient
class, which is suitable when you have SessionAuthentication
.
From the docs:
The
login
method is appropriate for testing APIs that use session authentication, for example web sites which include AJAX interaction with the API.
But in your view you use BasicAuthentication
(which is actually only suitable for testing purposes), so you may use another method of the client class - force_authenticate
:
class ViewTest(APITestCase):
def setUp(self):
...
self.client = APIClient()
self.client.force_authenticate(user=self.admin)
This would make your admin user actually logged in and the status code assert should pass successfully.