Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing functional tests for Django RESTful API

I'm trying to write some functional tests for a REST API written using Django REST Framework. It's not very specific to that framework though, since it's mostly general Django stuff.

This is what I want to do

  1. Create a user in the setUp method of the test class
  2. Request the users token from the API using the test client

tests.py

from django.test import LiveServerTestCase

from django.contrib.auth.models import User
from django.test.client import Client
from rest_framework.authtoken.models import Token

class TokenAuthentication(LiveServerTestCase):
    def setUp(self):
        user = User.objects.create(username='foo', password='password', email="[email protected]")
        user.save()
        self.c = Client()

    def test_get_auth_token(self):
        user = User.objects.get(username="foo")
        print user # this outputs foo
        print Token.objects.get(user_id = user.pk) # this outputs a normal looking token
        response = self.c.post("/api-token-auth/", {'username': 'foo', 'password': 'password'})
        print response.status_code # this outputs 400
        self.assertEqual(response.status_code, 200, "User couldn't log in")

When I run the test it returns status 400 rather than 200, so the user wasn't authenticated. If I enter the credentials of a user already in the database it passes though. So I assume records created in the test class are only accessible within it's own methods, which is probably because it's designed for unit testing. But I use data from the database to perform the test it will fail if the data changes.

How should a functional test like this, where data needs to be created before running the test, be performed in Django?

like image 360
Joar Leth Avatar asked Jan 13 '23 18:01

Joar Leth


1 Answers

You are creating the user incorrectly. User.objects.create sets the password in plain-text rather than through the hashing mechanism. You should instead be using User.objects.create_user which will properly set the password so that you can authenticate with the username and password.

like image 89
Mark Lavin Avatar answered Jan 22 '23 00:01

Mark Lavin