views:

413

answers:

4

I have django code that interacts with request objects or user objects. For instance something like:

foo_model_instance = models.get_or_create_foo_from_user(request.user)

If you were going to test with the django python shell or in a unittest, what would you pass in there? Here simply a User object will do, but the need for a mock request object also comes up frequently.

For the shell or for unittests:

  • How do you mock users?
  • How do you mock requests?
+4  A: 

Read about mock objects here
http://en.wikipedia.org/wiki/Mock_object
http://www.mockobjects.com/

And use this python lib to mock a user
http://python-mock.sourceforge.net/

else you can write a simple Use class yourself, use this as a starting point

class MockUser(object):
    def __call__(self, *args, **kwargs):
        return self

    def __getattr__(Self, name):
        return self

add specfic cases etc etc

Anurag Uniyal
+6  A: 

How do you mock users?

Initialise a django.contrib.auth.models.User object. User.objects.create_user makes this easy.

How do you mock requests?

Initialise a django.http.HttpRequest object.

Of course, there are shortcuts depending on what you want to do. If you just need an object with a user attribute that points to a user, simply create something (anything) and give it that attribute.

ozan
+1: Mock? Why mock? Use the real thing.
S.Lott
+2  A: 

You don't need to mock Users, as you can just create one within your test - the database is destroyed after the test is finished.

To mock requests, use this snippet from Simon Willison.

Daniel Roseman
+3  A: 

You can either roll your own mocks, as Anurag Uniyal has suggested, or you can use a mocking framework.

In response to those saying you can just create an ordinary user as you would anyway in Django... I would suggest this defeats the point of the unit test. A unit test shouldn't touch the database, but by creating a user, you've changed the database, hence why we would want to mock one.

Michael Williamson
As Daniel mentioned, the test runner creates then destroys a test database for you, so you needn't worry about that.
ozan
Except if you're using the database, then it's not a unit test any more. It may still be a perfectly valid integration test, but it's not a unit test.
Michael Williamson