From 24e9d92af128cfffa4dcb37443da5b4c8329e55c Mon Sep 17 00:00:00 2001 From: Anler Hp Date: Wed, 2 Jul 2014 13:34:14 +0200 Subject: [PATCH] Decorator for overriding settings while testing Usage: ``` from tests.utils import set_settings @set_settings(FOO='bar') def test_something(): ... ``` --- tests/utils.py | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/utils.py b/tests/utils.py index b20f2bce..8367b2cf 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -14,7 +14,9 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import functools +from django.conf import settings from django.db.models import signals @@ -34,3 +36,53 @@ def signals_switch(): disconnect_signals, reconnect_signals = signals_switch() + + +def set_settings(**new_settings): + """Decorator for set django settings that will be only available during the + wrapped-function execution. + + For example: + @set_settings(FOO='bar') + def myfunc(): + ... + + @set_settings(FOO='bar') + class TestCase: + ... + """ + def decorator(testcase): + if type(testcase) is type: + namespace = {"OVERRIDE_SETTINGS": new_settings, "ORIGINAL_SETTINGS": {}} + wrapper = type(testcase.__name__, (SettingsTestCase, testcase), namespace) + else: + @functools.wraps(testcase) + def wrapper(*args, **kwargs): + old_settings = override_settings(new_settings) + try: + testcase(*args, **kwargs) + finally: + override_settings(old_settings) + + return wrapper + + return decorator + + +def override_settings(new_settings): + old_settings = {} + for name, new_value in new_settings.items(): + old_settings[name] = getattr(settings, name, None) + setattr(settings, name, new_value) + return old_settings + + +class SettingsTestCase(object): + @classmethod + def setup_class(cls): + cls.ORIGINAL_SETTINGS = override_settings(cls.OVERRIDE_SETTINGS) + + @classmethod + def teardown_class(cls): + override_settings(cls.ORIGINAL_SETTINGS) + cls.OVERRIDE_SETTINGS.clear()