Added TestCase.settings context manager to easily override settings in test methods.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16165 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2011-05-06 13:29:24 +00:00
parent 21027a05c2
commit 0dc6420b3e
3 changed files with 70 additions and 4 deletions

View File

@ -2,11 +2,12 @@ from __future__ import with_statement
import re import re
import sys import sys
from contextlib import contextmanager
from functools import wraps from functools import wraps
from urlparse import urlsplit, urlunsplit from urlparse import urlsplit, urlunsplit
from xml.dom.minidom import parseString, Node from xml.dom.minidom import parseString, Node
from django.conf import settings from django.conf import settings, UserSettingsHolder
from django.core import mail from django.core import mail
from django.core.management import call_command from django.core.management import call_command
from django.core.signals import request_started from django.core.signals import request_started
@ -341,6 +342,22 @@ class TransactionTestCase(ut2.TestCase):
""" """
restore_warnings_state(self._warnings_state) restore_warnings_state(self._warnings_state)
@contextmanager
def settings(self, **options):
"""
A context manager that temporarily sets a setting and reverts
back to the original value when exiting the context.
"""
old_wrapped = settings._wrapped
override = UserSettingsHolder(settings._wrapped)
try:
for key, new_value in options.items():
setattr(override, key, new_value)
settings._wrapped = override
yield
finally:
settings._wrapped = old_wrapped
def assertRedirects(self, response, expected_url, status_code=302, def assertRedirects(self, response, expected_url, status_code=302,
target_status_code=200, host=None, msg_prefix=''): target_status_code=200, host=None, msg_prefix=''):
"""Asserts that a response redirected to a specific URL, and that the """Asserts that a response redirected to a specific URL, and that the

View File

@ -1351,6 +1351,31 @@ For example::
This test case will flush *all* the test databases before running This test case will flush *all* the test databases before running
``testIndexPageView``. ``testIndexPageView``.
Overriding settings
~~~~~~~~~~~~~~~~~~~
.. method:: TestCase.settings
.. versionadded:: 1.4
For testing purposes it's often useful to change a setting temporarily
and revert to the original value after running the testing code. For
this use case Django provides a standard `Python context manager`_
:meth:`~django.test.TestCase.settings`, which can be used like this::
from django.test import TestCase
class LoginTestCase(TestCase):
def test_overriding_settings(self):
with self.settings(LOGIN_URL='/other/login/'):
response = self.client.get('/sekrit/')
self.assertRedirects(response, '/other/login/?next=/sekrit/')
This example will override the :setting:`LOGIN_URL` setting for the code
in the ``with`` block and reset its value to the previous state afterwards.
.. _`Python context manager`: http://www.python.org/dev/peps/pep-0343/
Emptying the test outbox Emptying the test outbox
~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1,8 +1,31 @@
from django.conf import settings from django.conf import settings
from django.utils import unittest from django.test import TestCase
class SettingsTests(TestCase):
class SettingsTests(unittest.TestCase): def test_override(self):
settings.TEST = 'test'
self.assertEqual('test', settings.TEST)
with self.settings(TEST='override'):
self.assertEqual('override', settings.TEST)
self.assertEqual('test', settings.TEST)
del settings.TEST
def test_override_change(self):
settings.TEST = 'test'
self.assertEqual('test', settings.TEST)
with self.settings(TEST='override'):
self.assertEqual('override', settings.TEST)
settings.TEST = 'test2'
self.assertEqual('test', settings.TEST)
del settings.TEST
def test_override_doesnt_leak(self):
self.assertRaises(AttributeError, getattr, settings, 'TEST')
with self.settings(TEST='override'):
self.assertEqual('override', settings.TEST)
settings.TEST = 'test'
self.assertRaises(AttributeError, getattr, settings, 'TEST')
# #
# Regression tests for #10130: deleting settings. # Regression tests for #10130: deleting settings.
@ -18,7 +41,8 @@ class SettingsTests(unittest.TestCase):
self.assertRaises(TypeError, delattr, settings, '_wrapped') self.assertRaises(TypeError, delattr, settings, '_wrapped')
class TrailingSlashURLTests(unittest.TestCase):
class TrailingSlashURLTests(TestCase):
settings_module = settings settings_module = settings
def setUp(self): def setUp(self):