40

次のサンプルコードでmock.patchを機能させようとしています。

from mock import patch
from collections import defaultdict

with patch('collections.defaultdict'):
  d = defaultdict()
  print 'd:', d

これにより、次のように出力されます。

d: defaultdict(None, {})

これは、defaultdictにパッチが適用されていないことを意味します。

from / importステートメントをストレートインポートステートメントに置き換えると、次のように機能します。

from mock import patch
import collections

with patch('collections.defaultdict'):
 d = collections.defaultdict()
 print 'd:', d

出力は次のとおりです。

d: <MagicMock name='defaultdict()' id='139953944084176'>

from / importを使用して呼び出しにパッチを適用する方法はありますか?

ありがとうございました

4

3 に答える 3

60

同じモジュールで何かにパッチを適用する場合は、次を使用できます__main__

from mock import patch
from collections import defaultdict

with patch('__main__.defaultdict'):
    d = defaultdict()
    print 'd:', d

ただし、インポートされたモジュールのモックを作成する場合は、そのモジュールの名前を使用して、正しい参照(または名前)にパッチを適用する必要があります。

# foo.py

from collections import defaultdict

def bar():
    return defaultdict()


# foo_test.py    

from mock import patch
from foo import bar

with patch('foo.defaultdict'):
    print bar()

ここでのポイントは、パッチがパッチを適用しているものへのフルパスを必要としているということです。__main__人々は頻繁に使用しないので(または、さらに言えば、現在のモジュールを参照する必要があるため)、これは現在のモジュールで何かにパッチを適用するときに少し奇妙に見えます。

于 2012-07-05T19:47:36.460 に答える
12

patch名前にパッチを適用することで機能します。(ローカル名前空間で)名前を使用してオブジェクトにアクセスしてcollections.defaultdictいる場合、名前にパッチを適用しても何も達成できません。https://docs.python.org/3/library/unittest.mock.html#where-to-patchdefaultdictのドキュメントを参照してください

于 2012-07-05T19:47:48.747 に答える
3

この場合、名前は非常に混乱する可能性があります。私たちは常に名前空間のクラス定義をモックしたいと思っています。名前空間は、インポートが行われるモジュールです。クラス定義は、その名前空間で使用される名前です。

具体的な例を見てみましょう。

  • myproj.utilitiesモジュールにはActorクラスが含まれています
  • myproj.applicationはこれを次のようにインポートしますfrom myproj.utilities import Actor
  • 私のテストはmy.proj.applicationを実行し、アクターをモックする必要があります

myproj.utilities.py

class Actor:
    def __init__(name):
        self.name = name

myproj.application.py

from myproj.utilities import Actor

class App:
    def __init__(name):
        self.actor = Actor(name)

テストコード

from mock import patch
from myproj.application import App

test:
  # format: patch('<namespace>.<Class>')
  # the namespace in which we with to mock
  # the class definition we wish to mock
  with patch('myproj.application.Actor'):
      app = App('Someone')
      print( type(app.actor) ) # expect a MagicMock

私は他のいくつかのアプローチを試しましたが、これは私にとってうまく機能します。私は上記のコードをテストしていませんが、代わりに私自身の特定のケースからそれを一般化しました。だから、少しずれているかもしれません。

于 2019-02-12T17:24:45.610 に答える