2017-03-09 50 views
3

我在問如何使用Python3在單元測試中模擬一個類屬性。我試過以下,這是有道理的,我下面的文檔,但它不工作:如何模擬一個屬性

foo.py:

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並運行試驗是這樣的:

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

這將更改錯誤,但不會讓一個訪問'foo.bar'得到模擬對象。 – jsbueno