19

テストの理由から、別の場所で使用されている装飾された関数の内部/元の関数をモックできる必要があります。

mydecorator.py で:

def my_decorator(f):
    def wrapped_f():
        print "decorated"
        f()
    return wrapped_f


@my_decorator
def function_to_be_mocked():
    print 'original'


def function_to_be_mocked_undecorated():
    print 'original'


def run_decorated():
    function_to_be_mocked()


def run_undecorated():
    decorated_funtion = my_decorator(function_to_be_mocked_undecorated)
    decorated_funtion()

ご覧のとおり、元の関数 function_to_be_mocked のいくつかのバージョンがあります。1 つはデコレーター my_decorator を使用し、もう 1 つは「ネイキッド」です。ランナー関数 run_decorated() は function_to_be_mocked の装飾されたバージョンを呼び出し、run_undecorated() は装飾されていないバージョンを呼び出し、デコレーターを「手動で」適用します。両方の結果は同じです。

decorated
original

ここで、ランナー関数をテストしたいのですが、元の関数 function_to_be_mocked をモックする必要がありますが、モックされたバージョンも装飾する必要があります。

import unittest
import mydecorator
from mock import patch

def mock_function():
    print 'mockified'

class Test(unittest.TestCase):

    @patch('mydecorator.function_to_be_mocked_undecorated')
    def test_undecorated_mocked(self, mock_function_to_be_mocked_undecorated):
        mydecorator.function_to_be_mocked_undecorated = mock_function
        mydecorator.run_undecorated()
        assert 1==0

    @patch('mydecorator.function_to_be_mocked')
    def test_decoratorated_mocked(self, mock_function_to_be_mocked):
        mydecorator.function_to_be_mocked = mock_function
        mydecorator.run_decorated()
        assert 1==0

これは、装飾されていないバージョンの test_undecorated_mocked で期待どおりに機能します。

decorated
mockified

しかし、装飾されたバージョンは次のようになります。

mockified

そのため、デコレータは消えました。

デコレータが「手動」で適用される、装飾されていないバージョンと同じように、装飾されたバージョンを動作させることは可能ですか?

デコレーターで内部関数を公開しようとしましたが、成功しませんでした。

この質問を見ましたユニットテストでデコレータが適用される関数をどのようにモックしますか? しかし、これは私を助けません。

4

1 に答える 1

19

Python はモジュールをロードするときにデコレーターを適用するため、 in に設定function_to_be_mockedすると、実際にその関数が装飾されていない関数に変更されます。mock_functiontest_decoratorated_mocked

モックしたい場合は、手動でデコレータを再度追加する必要がありますfunction_to_be_mocked:

mydecorator.function_to_be_mocked = mydecorator.my_decorator(mock_function)
于 2013-11-06T13:09:44.653 に答える