1

別のモジュールで関数を呼び出す単純なメソッドを置き換えるのに問題があります。私がモッキングについて理解していることから、呼び出されているメソッドを参照する必要があります(元のメソッドではなく、そのコンテキストで)。以下は、私が実行しているものの簡略化されたバージョンであり、モックについて学ぶ必要があるのは簡単なものであることを願っています. パッチは Class および Class メソッドのみに使用することを意図していますか、それともここで何か間違ったことをしていますか?

ありがとう、スティーブ

myapp.models.py

from myapp.backends import get_backend
class BasicClass(models.Model):
    @staticmethod
    def basic_method()
        be = get_backend()
        print be

myapp.backends._ init _.py

def get_backend():
    return 'original value'

test.py

# Referencing the import in myapp.models.basic_class 
# vs directly importing myapp.backends
# as indicated here: 
# http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch
from myapp.models import get_backend
from myapp.models.basic_class import BasicClass

class ParsersTest(TestCase):

    @patch('myapp.models.get_backend')
    def test_simplified(self, moves_backend):
        # Assertion fails
        assert get_backend is moves_backend
        # Assuming that assertion fails is why the original return value is always returned
        moves_backend.return_value = 'new return value'
        BasicClass.basic_method()
4

2 に答える 2

0

あなたは誤解していると思います。覚えておいてください: Python では、モジュールとクラスのメンバーは (多かれ少なかれ) 単なる変数です。たまたまメソッドが含まれている可能性がありますが、それらは単なる変数です。別のモジュールから何かをインポートすると、インポート元のモジュールに変数が作成され、オブジェクトがドロップされます。

デコレーター@patch('myapp.models.get_backend')は、変数をmyapp.modelsモック オブジェクトに置き換えるだけです。これはあなたが望むものではありません。パッチが適用されるまでに、myapp.models.basic_classは既にインポートされているため、 から実際のメソッドへの参照が既にインポートされていmyapp.modelsます。(つまり、そのget_backend変数はすでに実際のメソッドを保持しています。)実際に使用されている変数を次のように置き換えますmyapp.models.basic_class

@patch('myapp.models.basic_class.get_backend')

get_backendこれにより、変数がmyapp.models.basic_classモックで埋められます。したがって、 を呼び出すとBasicClass.basic_method()、変数basic_methodmyapp.models.basic_class.get_backendを調べてモックを見つけます。

だからこれを試してください:

from myapp.models import basic_class

class ParsersTest(TestCase):
    @patch('myapp.models.basic_class.get_backend')
    def test_simplified(self, moves_backend):
        assert basic_class.get_backend is moves_backend
        moves_backend.return_value = 'new return value'
        basic_class.BasicClass.basic_method()

とはいえ、何をテストするかに注意してください。ありとあらゆる方法ですべてをテストする必要はありません。テストを作成する前に、このテストがどのような価値を提供するかを検討してください。

于 2014-02-05T03:52:00.563 に答える