1

その時点で利用できず動作しないリソースを必要とするモジュール (ResourceX) をインポートする MyApp をシミュレートしたいと考えています。

これに対する解決策は、ResourceX のモック モジュール (ResourceXSimulated という名前) を作成してインポートし、それを ResourceX として MyApp に流用することです。多くのコードを壊さないようにし、MyApp からあらゆる種類の例外を取得するために、これを行いたいと考えています。

私はPythonを使用していますが、次のようになります。

「ResourceXSimulated を ResourceX としてインポート」

「ResourceX.getData()」、実際には ResourceXSimultated.getData() を呼び出します

Python がこの種のリダイレクトをサポートしているかどうかを調べるのを楽しみにしています。

乾杯。

追加情報: ソース ファイルにアクセスできます。

更新: 偽のモジュールの使用に関して MyApp にできるだけ少ないコードを追加し、インポート ステートメントの近くにこのコードを追加することを考えています。

4

5 に答える 5

4

すべての行import ResourceXを に変更MyAppimport ResourceXSimulated as ResourceX、行from ResourceX import Yをに変更するだけfrom ResourceXSimulated import Yです。

ただし、ソースにアクセスできない場合、MyAppまたはソースを変更しない他の理由がある場合は、モジュール自体をロードするsys.modules前にモジュールを配置できます。MyApp

import ResourceXSimulated
sys.modules['ResourceX'] = ResourceXSimulated

注:ResourceXがパッケージの場合は、より多くの作業が必要になる場合があります。

于 2009-09-18T08:42:26.690 に答える
1

はい、可能です。いくつかの初心者:

sys.modules を操作することで、モジュールを「流用」できます。インポートされたモジュールのリストを保持し、元のモジュールと同じ名前でモジュールを表示することができます。ただし、偽造したいモジュールをインポートするモジュールの前に、この操作を行う必要があります。

別の名前のパッケージを作成することもできますが、そのパッケージでは実際には元のモジュール名を使用して、まったく別のモジュールを作成します。元のモジュールがインストールされていない限り、これはうまく機能します。

これらのケースのいずれにおいても、両方のモジュールを同時に使用することはできません。そのためには、元のモジュールにモンキー パッチを適用する必要があります。

もちろん、新しいモジュールを古い名前で呼び出すことも完全に可能です。しかし、それは混乱するかもしれません。

于 2009-09-18T08:41:06.583 に答える
1

これはモンキー パッチと呼ばれ、Python などの動的言語でかなり広く使用されている手法です。

したがって、おそらく次のクラスがあります。

class MyOriginal(object):

    def method_x(self):
        do_something_expensive_you_dont_want_in_testing()


obj = MyOriginal()
obj.method_x()

したがって、テストでは の代わりに何か他のことをしたいのですmethod_xが、それは透過的でなければなりません。したがって、Python の動的言語を利用するだけです。

def new_method_x(self):
    pretend_were_doing_something_expensive()

test_obj = MyOriginal()
test_obj.method_x = new_method_x # here's the monkeypatch
test_obj_method_x() # calls the new method
于 2009-09-18T08:35:32.070 に答える
1

sys.modulesすでに述べたように、ハックで可能です。

モジュールを制御できる場合は、モジュールResourceX自体が処理する方が確実に優れていることに注意してください。これは実際には、何らかのリソースが存在する場合にうまく機能するモジュールを作成する場合の一般的なパターンです。たとえば、次のようになります。

# foo.py
'''A module that provides interface to foo. 

Falls back to a dummy interface if foo is not available.
'''

try:
    from _foo import *
except ImportError:
    from _foo_dummy import *

時には、よりオブジェクト指向の方法でそれを行う人もいます:

# foo.py
'''A module that provides interface to foo if it exists or to a dummy interface. 

Provides:
    frobnicate()   self-explanatory
    ...
'''

class DummyFoo:
    def frobnicate(self):
        pass
    ...

class UnixFoo(DummyFoo):
    def frobnicate(self):
        a_posix_call()
    ...

class GenericFoo(DummyFoo):
    def frobnicate(self):
        do_something_complicated()
    ...

# Create a default instance.
try:
   if (system == UNIX)
       instance = UnixFoo(system)
   else:
       instance = GenericFoo()
except Exception:
    instance = DummyFoo()

# Now export the public interface.
frobnicate = instance.frobnicate
于 2009-09-18T08:55:00.673 に答える
0

はい、Python はそれを行うことができます。また、ResourceXSimulated モジュールで公開されているメソッドが元のモジュールと同じように「見た目と匂い」がする限り、アプリケーションはほとんど違いを認識しないはずです (偽のデータ フィラーを除いて、私は想定しています)。 、異なる応答時間など)。

于 2009-09-18T08:20:33.753 に答える