5

モックパッチがどのように機能するのか、問題を解決できるのか理解できません。

外部インターフェイスとの通信 (a.py)、ビジネス ロジック (b.py)、テスト (test.py) の 3 つのファイルがあります。テストの実行中にビジネス ロジックで使用される外部インターフェイスにパッチを適用したいと考えています。

a.py:

class SomeProductionClassINeedPatch(object):
    name = 'Production Class (communication with some external service)'
    def do_something(self):
        print '<some feature with external service>'

b.py:

import mock
from src.tmp.mocks.a import SomeProductionClassINeedPatch

class WorkingClass(object):
    def some_method_that_uses_external_class(self, *args):
        external = self._external
        external.do_something()

    @property
    def _external(self):
        if not hasattr(self, '_ext_obj' or not self._ext_obj):
            self._ext_obj = SomeProductionClassINeedPatch()
            print isinstance(self._ext_obj, mock.MagicMock) # False
        return self._ext_obj

b = WorkingClass()
b.some_method_that_uses_external_class()

test.py:

import mock
from src.tmp.mocks.b import WorkingClass    # class I want to test

@mock.patch('src.tmp.mocks.a.SomeProductionClassINeedPatch')
def test_some_method_of_working_class(external_mock=None, *args):
    o = WorkingClass()
    o.some_method_that_uses_external_class()        # external interface wasn't patched: <some feature with external service> - but I need mock here!
    print '<test> - '+str(isinstance(o._external, mock.MagicMock))  # False

test_some_method_of_working_class()

test.py でo.some_method_that_uses_external_class () を呼び出すと、実際には外部インターフェイスは使用されず、モック オブジェクトが使用されると予想されます。しかし、まだ実際のオブジェクトが使用されているようです。

また、test.py または b.py で外部インターフェイス オブジェクトのインスタンスをチェックすると、isinstance(object, MagicMock)チェックを通過させることができず、常に false が返されます。b.pyに同じパッチを適用しようとしても(クラス デコレータとして)。私は何を間違っていますか?

問題がある場合は、マイケル・フードによるpython 2.7とモック・ライブラリー1.0を使用します。

4

1 に答える 1

2

パッチを適用する場所に記載されているように:

パッチは、名前が指すオブジェクトを別のオブジェクトに (一時的に) 変更することによって機能します。個々のオブジェクトを指す名前が多数ある可能性があるため、パッチを適用するには、テスト対象のシステムで使用される名前にパッチを適用する必要があります。

あなたの例では、パッチを適用するオブジェクトを使用するコードは module にありますb。patch を呼び出すと、クラスはすでにモジュールbにインポートされているため、パッチaを適用しても には影響しませんb。代わりに、次のオブジェクトをパスする必要がありますb

@mock.patch('src.tmp.mocks.b.SomeProductionClassINeedPatch')

これにより、期待される結果が得られます。 からの最初の呼び出しにbはパッチが適用されていませんが、 からの 2 番目の呼び出しでtestはモック オブジェクトが使用されます。

# python test.py
False
<some feature with external service>
True
<test> - True
于 2013-04-17T22:38:43.267 に答える