2017-03-09 13 views
3

私はPython3を使って単体テストでクラスプロパティを模擬する方法を尋ねています。プロパティをモックする方法

class Foo(): 

    @property 
    def bar(self): 
     return 'foobar' 


def test_foo_bar(mocker): 
    foo = Foo() 
    mocker.patch.object(foo, 'bar', new_callable=mocker.PropertyMock) 
    print(foo.bar) 

私はpytestpytest_mockをインストールして実行:私は、ドキュメントを、次の私のために理にかなっている、次のことを試してみたが、それは動作しません:

foo.pyテストのように:

py.test foo.py 

私は、次のエラーを得た:

>  setattr(self.target, self.attribute, new_attr) 
E  AttributeError: can't set attribute 

/usr/lib/python3.5/unittest/mock.py:1312: AttributeError 

私の期待は、テストをエラーなく実行することです。

答えて

5

プロパティのメカニズムは、オブジェクトのクラスで定義されているプロパティの属性に依存します。 Pythonのdescriptor protocolについては、よく理解するために、「プロパティのような」メソッドや属性を作成することはできません。

したがって、クラスにパッチを適用する必要があります。クラスが適切にテストした後に復元されるようにwith声明:

def test_foo_bar(mock): 
    foo = Foo() 
    with mock.patch(__name__ + "Foo.bar", new=mocker.PropertyMock) 
     print(foo.bar) 
+0

確かに - 私はそれがあなたの言うように働いていた - 私はちょうど失敗した後の裁判を貼り付けた。 – jsbueno

+0

私は答えを編集しました - これは実際に私のために働いたものです。 – jsbueno

+0

それは動作します!また、ディスクリプタプロトコルに関するリンクにも感謝します。確かに、これまでのところどのようにプロパティが実装されているのか分かりません。それを通り過ぎるだろう。 – hek2mgl

0

@bar.setterがありません。

@bar.setter 
def bar(self, foo): 
    self.__bar = foo 
+1

これはエラーを変更しますが、モックオブジェクトを取得するには1アクセス 'foo.bar'をすることはありません。 – jsbueno

関連する問題