2012-12-24 60 views
1

我的模型中有一個@memoize裝飾器,它可以緩存模型本身的一些細節,以避免多次調用多個數據庫調用時(特別是在模板中)。但是,由於我存儲了對象並在測試中引用它們,所以這會使事情失敗。如何在測試時在Django的模型中修飾裝飾器?

例如,如果我做mygroup.subscribers,添加一個訂戶並再次嘗試它,它將返回不正確的訂戶數,因爲它已被記憶。

我怎樣才能讓修飾器在我的tests.py中無所作爲?我還沒有找到一種乾淨利落的方法,因爲模型首先被加載。

回答

0

截至memoize實施之初,檢查它是否在測試模式下按本answer

from django.core import mail 

# at the beginning of your memoize 
if hasattr(mail, 'outbox'): 
    # return without memorizing 
+0

我寧願避免在那裏添加測試代碼,因爲我想繼續測試包含在我的tests.py中的代碼。不過謝謝你的回答! –

0

你可以在你test runner禁用你的裝飾,測試環境將設立前模型加載。

例如:

from django.test.simple import DjangoTestSuiteRunner 
from utils import decorators 

class PatchTestSuiteRunner(DjangoTestSuiteRunner): 
    def setup_test_environment(self, **kwargs): 
     super(PatchTestSuiteRunner, self).setup_test_environment(**kwargs) 
     self.__orig_memoize = decorators.memoize 
     decorators.memoize = lambda x: x 

    def teardown_test_environment(self, **kwargs): 
     decorators.memoize = self.__orig_memoize 
     super(PatchTestSuiteRunner, self).teardown_test_environment(**kwargs) 

然後把你的settings.py

TEST_RUNNER = 'test.PatchTestSuiteRunner' 

而且測試可以不用記憶化運行:

# myapp/models.py 
class TestObject(object): 
    def __init__(self, value): 
     self.value = value 

    @memoize 
    def get_value(self): 
     return self.value 

# myapp/test.py 
from django.test import TestCase 
from .models import TestObject 

class NoMemoizeTestCase(TestCase): 
    def test_memoize(self): 
     t = TestObject(0) 
     self.assertEqual(t.get_value(), 0) 
     t.value = 1 
     self.assertEqual(t.get_value(), 1) 

注意,雖然我們正在恢復在測試跑步者的原始裝飾者的teardown_test_environment,記憶將n不能在已經裝飾的功能上恢復。如果我們使用更復雜的測試裝飾器,則可以恢復記憶,但在標準用例中這可能不是必需的。