2

一部のクラスは、クラス レベル (外部__init__またはその他の関数) で属性 (別名フィールド) を定義します。一部のクラスは、それらを__init__関数内で定義するか、他の関数から定義します。一部のクラスでは、両方のアプローチを使用します。

class MyClass(object):
  foo = 'foo'
  def __init__(self, *args, **kwargs):
    self.bar = 'bar'

問題は、を使用すると、クラスのインスタンスを渡す場合dirにのみ含まれることです。'bar'

>>> dir(MyClass)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'foo']
>>> myInstance = MyClass()
>>> dir(myInstance)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo']

(一番右にスクロールして差分を表示します)

インスタンス化を避ける必要がある状況がありますが、単体テストの呼び出しで (チェックを渡すためMyClassの) 設定として使用したいと考えています。specisinstancemock.patch

@mock.patch('mypackage.MyClass', spec=MyClass)
def test_thing_that_depends_on_MyClass(self, executeQueryMock):
  # uses 'thing' here, which uses MyClass.bar ...

これを行うと、次の原因になります。

AttributeError: モック オブジェクトに属性 'bar' がありません

モック ドキュメントに次のように記載されているため、これは理にかなっています。

spec: これは、文字列のリストまたはモック オブジェクトの仕様として機能する既存のオブジェクト (クラスまたはインスタンス) のいずれかです。オブジェクトを渡すと、オブジェクトで dir を呼び出すことによって文字列のリストが形成されます (サポートされていないマジック属性とメソッドを除く)。このリストにない属性にアクセスすると、AttributeError が発生します。

インスタンス化してもMyClass、別のエラーが発生します。

@mock.patch('mypackage.MyClass', spec=MyClass())
def test_thing_that_depends_on_MyClass(self, executeQueryMock):
  # uses 'thing' here, which uses MyClass.bar ...

原因:

TypeError: 'NonCallableMagicMock' オブジェクトは呼び出し可能ではありません

アクセスを許可する関数/属性に厳密であることはあまり気にしません。私は実際には、 なしで何かを呼び出すことができる通常の MagicMock の動作が必要ですAttributeError。チェックに合格するためspecに使用しているだけでも、使用するとこれが厳密になるようです。specisinstance

質問:

isinstanceチェックで使用され、クラスレベルで定義されていない属性を持つこのクラスを適切にモックするにはどうすればよいですか?

4

1 に答える 1