1

我的模型中有一个@memoize装饰器,它缓存了模型本身的一些细节,以避免在多次调用时(尤其是在模板中)多次调用数据库。但是,由于我存储对象并在测试中引用它们,这会破坏事情。

例如,如果我mygroup.subscribers添加了一个订阅者并重试,它将返回错误的订阅者数量,因为它已被记忆。

我怎样才能在我的tests.py中对那个装饰器进行猴子补丁以不做任何事情?我还没有找到一种干净的方法,因为模型首先被加载。

4

2 回答 2

0

在实施开始时,根据此答案memoize检查它是否处于测试模式:

from django.core import mail

# at the beginning of your memoize
if hasattr(mail, 'outbox'):
    # return without memorizing
于 2012-12-24T16:52:44.987 回答
0

您可以在测试运行器中禁用您的装饰器,测试环境将在加载模型之前设置。

例如:

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不会在已装饰的函数上恢复记忆。如果我们使用更复杂的测试装饰器,可以恢复记忆,但这在标准用例中可能不是必需的。

于 2013-04-19T07:26:35.590 回答