我的模型中有一個@memoize
裝飾器,它可以緩存模型本身的一些細節,以避免多次調用多個數據庫調用時(特別是在模板中)。但是,由於我存儲了對象並在測試中引用它們,所以這會使事情失敗。如何在測試時在Django的模型中修飾裝飾器?
例如,如果我做mygroup.subscribers
,添加一個訂戶並再次嘗試它,它將返回不正確的訂戶數,因爲它已被記憶。
我怎樣才能讓修飾器在我的tests.py中無所作爲?我還沒有找到一種乾淨利落的方法,因爲模型首先被加載。
我的模型中有一個@memoize
裝飾器,它可以緩存模型本身的一些細節,以避免多次調用多個數據庫調用時(特別是在模板中)。但是,由於我存儲了對象並在測試中引用它們,所以這會使事情失敗。如何在測試時在Django的模型中修飾裝飾器?
例如,如果我做mygroup.subscribers
,添加一個訂戶並再次嘗試它,它將返回不正確的訂戶數,因爲它已被記憶。
我怎樣才能讓修飾器在我的tests.py中無所作爲?我還沒有找到一種乾淨利落的方法,因爲模型首先被加載。
截至memoize
實施之初,檢查它是否在測試模式下按本answer:
from django.core import mail
# at the beginning of your memoize
if hasattr(mail, 'outbox'):
# return without memorizing
你可以在你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不能在已經裝飾的功能上恢復。如果我們使用更復雜的測試裝飾器,則可以恢復記憶,但在標準用例中這可能不是必需的。
我寧願避免在那裏添加測試代碼,因爲我想繼續測試包含在我的tests.py中的代碼。不過謝謝你的回答! –