How to define headers for authorization in django testing?

Question:

I want to write a test case for a function in my views in my Django project. I am just a beginner in this field, I have changed my settings.py and added the below line of code to the DATABASES dictionary, and also create a new user using MySQL shell based on this post:

'TEST': {
    'NAME': 'test_sepantadb',
}

In function, there is a try/catch for checking the authorization using the request.headers. Here is the API code:

@api_view(['GET'])
def Get_users(request, **kwargs):
    try:
        user = request.headers['Authorization']
        p = Profile.objects.get(username=user)
    except Exception as e:
        print(e)
        return Response(status=status.HTTP_401_UNAUTHORIZED)
    
    users = Device.objects.filter(owner=p)
    res = []
    for u in users:
        user_inf = {}
        try:
            pdm = PersonDeviceMapper.objects.filter(device=u)[0]
            prof = pdm.person
            user_inf['name'] = prof.name
            user_inf['username'] = prof.username
        except Exception as e:
            print(e)
            user_inf['name'] = u.name
            user_inf['username'] = "default_" + str(u.id)
        user_inf['created_at'] = u.created_at
        user_inf['id'] = u.id
        user_inf['device_id'] = u.device_id
        res.append(user_inf)
    return Response(res)

And here is the code in models.py for Profile class:

class Profile(models.Model):
    GENDER_MALE = 1
    GENDER_FEMALE = 2
    GENDER_CHOICES = [
        (GENDER_MALE, _("Male")),
        (GENDER_FEMALE, _("Female")),
    ]
    code = models.IntegerField(null=True, blank=True)
    username = models.CharField(max_length=128, null=False, blank=False, unique=True)
    password = models.CharField(max_length=128, null=False, blank=False)
    name = models.CharField(max_length=50, null=True, blank=True)
    lastname = models.CharField(max_length=50, null=True, blank=True)
    birthday = models.DateField(null=True, blank=True)
    gender = models.PositiveSmallIntegerField(choices=GENDER_CHOICES, null=True, blank=True)
    phone = models.CharField(max_length=32, null=True, blank=True)
    address = models.CharField(max_length=255, null=True, blank=True)
    number = models.CharField(max_length=32, null=True, blank=True)
    city = models.CharField(max_length=50, null=True, blank=True)
    zip = models.CharField(max_length=30, null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    def __str__(self):
        return self.username

I did not use the default User in Django, and this is the code for my test:

class TestViews(TestCase):
    def setUp(self):
        self.client = Client()
        self.users_url = reverse('react:get users')

    def test_users_GET(self):
        headers = {'AUTHORIZATION': 'demo'}
        response = self.client.get(self.users_url, **headers)
        self.assertEqual(response.status_code, 200)

demo is the name of the account that I use for testing the response in postman either.
enter image description here
But after I run the test it shows this error:

Failure
Traceback (most recent call last):
  File "D:ABDALsepantareactteststest_views.py", line 26, in test_users_GET
    self.assertEqual(response.status_code, 200)
AssertionError: 401 != 200

I could not understand the reason for this problem, and I have also searched for similar problems, but they did not help me. Does Django create a new database while testing the APIs? and the reason can be because of that the database is empty.

Asked By: Aylin Naebzadeh

||

Answers:

Django always create a separate database for testing. Just so you know, the database is also always destroyed after running tests.
However, you can provide a flag to keep test database.
You can read more on that here

To solve your problem, you need to create a new Profile within your test (test fixtures). You will typically want to do that in the setUp method.

NB: The profile created has nothing to do with your normal or real database and in fact you can check the id of the profile and realize it will be 1 despite having profiles in your database. That even assert to the fact that a separate database is used for testing.

Answered By: FAYEMI BOLUWATIFE