115

mock を使用して読み取り専用プロパティをモックするにはどうすればよいですか?

私は試した:

setattr(obj.__class__, 'property_to_be_mocked', mock.Mock())

しかし問題は、それがクラスのすべてのインスタンスに適用されることです...これは私のテストを壊します。

他に何か考えはありますか?オブジェクト全体をモックするのではなく、この特定のプロパティのみをモックします。

4

9 に答える 9

216

メソッドを直接PropertyMockモックするよりも、プロパティを としてモックする方が良いと思います。__get__

これはドキュメントに記載されています。次を検索してunittest.mock.PropertyMockください:クラスのプロパティまたはその他の記述子として使用されることを意図したモック。とメソッドPropertyMockを提供しているため、取得時に戻り値を指定できます。__get____set__

方法は次のとおりです。

class MyClass:
    @property
    def last_transaction(self):
        # an expensive and complicated DB query here
        pass

def test(unittest.TestCase):
    with mock.patch('MyClass.last_transaction', new_callable=PropertyMock) as mock_last_transaction:
        mock_last_transaction.return_value = Transaction()
        myclass = MyClass()
        print myclass.last_transaction
        mock_last_transaction.assert_called_once_with()
于 2014-08-21T10:28:54.713 に答える
44

実際、答えは(いつものように)ドキュメントにありました。例に従ったときに、クラスではなくインスタンスにパッチを適用しただけです。

方法は次のとおりです。

class MyClass:
    @property
    def last_transaction(self):
        # an expensive and complicated DB query here
        pass

テスト スイートで:

def test():
    # Make sure you patch on MyClass, not on a MyClass instance, otherwise
    # you'll get an AttributeError, because mock is using settattr and
    # last_transaction is a readonly property so there's no setter.
    with mock.patch(MyClass, 'last_transaction') as mock_last_transaction:
        mock_last_transaction.__get__ = mock.Mock(return_value=Transaction())
        myclass = MyClass()
        print myclass.last_transaction
于 2012-08-07T10:17:53.097 に答える
11

おそらくスタイルの問題ですが、テストでデコレータを好む場合は、@ jamescastlefield の答えを次のように変更できます。

class MyClass:
    @property
    def last_transaction(self):
        # an expensive and complicated DB query here
        pass

class Test(unittest.TestCase):
    @mock.patch('MyClass.last_transaction', new_callable=PropertyMock)
    def test(self, mock_last_transaction):
        mock_last_transaction.return_value = Transaction()
        myclass = MyClass()
        print myclass.last_transaction
        mock_last_transaction.assert_called_once_with()
于 2017-01-10T14:28:42.670 に答える
1

モックされたプロパティがアクセスされたかどうかをテストしたくない場合は、単に期待される でパッチを当てることができますreturn_value

with mock.patch(MyClass, 'last_transaction', Transaction()):
    ...
于 2017-03-07T00:46:13.837 に答える