views:

435

answers:

3

I have a requirement something like this:

As soon as the user signsup(and will be in the waiting state untill he confirms his email address), a session variable is set something like "FIRST_TIME_FREE_SESSION_EXPIRY_AGE_KEY"(sorry if the name sounds confusing!) which will be set to a datetime object adding 8hrs to the current time.

How this should impact the user is, the user gets 8hrs time to actually use all the features of our site, without confirming his signedup email address. After 8hrs, every view/page will show a big banner telling the user to confirm. (All this functionality is achieved using a single "ensure_confirmed_user" decorator for every view).

I want to test the same functionality using django's unittest addon(TestCase class). How do I do it?

Update: Do I need to manually update the mentioned session variable value(modified 8hrs to a few seconds) so as to get it done? Or any better way is there?

Update: This may sound insane, but I want to simulate a request from the future.

A: 

I can think of a couple of possibilities. During your test run, override the FIRST_TIME_FREE_SESSION_EXPIRY_AGE_KEY variable and set it to a smaller time limit. You can then wait until that time limit is over and verify if the feature is working as expected.

Alternately replace your own datetime functions (assuming your feature relies on datetime)

You can accomplish these by overriding setup_ and teardown_test_environment methods.

Manoj Govindan
+2  A: 

Generally, if unit testing is difficult because the product code depends on external resources that won't cooperate, you can abstract away those resources and replace them with dummies that do what you want.

In this case, the external resource is the time. Instead of using datetime.now(), refactor the code to accept an external time function. It can default to datetime.now. Then in your unit tests, you can change the time as the test progresses.

This is better than changing the session timeout to a few seconds, because even then, you have to sleep for a few seconds in the test to get the effect you want. Unit tests should run as fast as you can get them to, so that they will be run more often.

Ned Batchelder
A: 

My settings.py differs slightly depending on whether django is run in a production environment or in a development environment. I have 2 settings modules: settings.py and settings_dev.py. The development version looks as follows:

from settings import *

DEBUG = True

INSTALLED_APPS = tuple(list(INSTALLED_APPS) + [
            'dev_app',
            ])

Now you can solve your problem in different ways:

  1. add the variable with different values to both settings modules;
  2. Where you set the variable, choose between two values according to the value of the DEBUG setting. You can also use DEBUG to omit the unit test when on the production server, because the test will probably take too long there anyway.

You can use the active settings module like this:

from django.conf.project_template import settings

if settings.DEBUG:
    ...
lbp