Search code examples
djangowebtestdjango-testing

How do I get the user in Django test?


I have some external services. My Django app is built on top of my external service APIs. In order to talk to my external service, I have to pass in an auth cookies, which I can get by reading User (that cookie != django cookies).

Using test tools like webtests, requests, I have trouble writing my tests.

class MyTestCase(WebTest):
    def test_my_view(self):
        #client = Client()
        #response = client.get(reverse('create')).form
        form = self.app.get(reverse('create'), user='dummy').form
        print form.fields.values()
        form['name'] = 'omghell0'
        print form

        response = form.submit()

I need to submit a form, which creates, say, a user on my external service. But to do that, I normally would pass in request.user (in order to authenticate my privilege to external service). But I don't have request.user.

What options do I have for this kind of stuff?

Thanks...


Suppose this is my tests.py

import unittest
from django.test.client import Client
from django.core.urlresolvers import reverse
from django_webtest import WebTest
from django.contrib.auth.models import User


class SimpleTest(unittest.TestCase):
    def setUp(self):
        self.usr = User.objects.get(username='dummy')
        print self.usr
    .......

I get

Traceback (most recent call last):
  File "/var/lib/graphyte-webclient/webclient/apps/codebundles/tests.py", line 10, in setUp
    self.usr = User.objects.get(username='dummy')
  File "/var/lib/graphyte-webclient/graphyte-webenv/lib/python2.6/site-packages/django/db/models/manager.py", line 132, in get
    return self.get_query_set().get(*args, **kwargs)
  File "/var/lib/graphyte-webclient/graphyte-webenv/lib/python2.6/site-packages/django/db/models/query.py", line 341, in get
    % self.model._meta.object_name)
DoesNotExist: User matching query does not exist

But if I test the User.objects in views, I am okay.


Solution

  • You need to use the setUp() method to create test users for testing - testing never uses live data, but creates a temporary test database to run your unit tests. Read this for more information: https://docs.djangoproject.com/en/dev/topics/testing/?from=olddocs#writing-unit-tests

    EDIT:

    Here's an example:

    from django.utils import unittest
    from django.contrib.auth.models import User
    
    from myapp.models import ThisModel, ThatModel
    
    class ModelTest(unittest.TestCase):
        def setUp(self):
            # Create some users
            self.user_1 = User.objects.create_user('Chevy Chase', '[email protected]', 'chevyspassword')
            self.user_2 = User.objects.create_user('Jim Carrey', '[email protected]', 'jimspassword')
            self.user_3 = User.objects.create_user('Dennis Leary', '[email protected]', 'denisspassword')
    

    Also note that, if you are going to use more than one method to test different functionality, you should use the tearDown method to destroy objects before reinstantiating them for the next test. This is something that took me a while to finally figure out, so I'll save you the trouble.

    def tearDown(self):
            # Clean up after each test
            self.user_1.delete()
            self.user_2.delete()
            self.user_3.delete()