1

モデルには@memoizeデコレータがあり、モデル自体の詳細をキャッシュして、何度も呼び出されたときに複数のデータベース呼び出しを回避します (特にテンプレートで)。ただし、オブジェクトを保存してテストで参照しているため、問題が発生します。

たとえばmygroup.subscribers、サブスクライバーを追加して再試行すると、メモ化されているため、間違った数のサブスクライバーが返されます。

私のtests.pyから何もしないように、そのデコレータにモンキーパッチを適用するにはどうすればよいですか? モデルが最初にロードされるため、きれいに行う方法が見つかりませんでした。

4

2 に答える 2

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 に答える
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 に答える