From c287062fcf8b891db3b982e628cb297165b766e2 Mon Sep 17 00:00:00 2001 From: Michael Foord Date: Fri, 13 Apr 2012 16:57:22 +0100 Subject: [PATCH] unittest.mock.PropertyMock return value and attributes are now standard MagicMocks --- Doc/library/unittest.mock.rst | 11 +++++++++++ Lib/unittest/mock.py | 3 +++ Lib/unittest/test/testmock/testhelpers.py | 11 +++++++++++ 3 files changed, 25 insertions(+) diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index df1c41fae8c..f00d29f028e 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -712,6 +712,17 @@ have to create a dictionary and unpack it using `**`: >>> mock_foo.mock_calls [call(), call(6)] +Because of the way mock attributes are stored you can't directly attach a +`PropertyMock` to a mock object. Instead you can attach it to the mock type +object:: + + >>> m = MagicMock() + >>> p = PropertyMock(return_value=3) + >>> type(m).foo = p + >>> m.foo + 3 + >>> p.assert_called_once_with() + Calling ~~~~~~~ diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 0a9aece8458..ec175426694 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -2166,6 +2166,9 @@ class PropertyMock(Mock): Fetching a `PropertyMock` instance from an object calls the mock, with no args. Setting it calls the mock with the value being set. """ + def _get_child_mock(self, **kwargs): + return MagicMock(**kwargs) + def __get__(self, obj, obj_type): return self() def __set__(self, obj, val): diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/unittest/test/testmock/testhelpers.py index 3674778c6d6..a2ed1003071 100644 --- a/Lib/unittest/test/testmock/testhelpers.py +++ b/Lib/unittest/test/testmock/testhelpers.py @@ -831,5 +831,16 @@ class TestCallList(unittest.TestCase): p.stop() + def test_propertymock_returnvalue(self): + m = MagicMock() + p = PropertyMock() + type(m).foo = p + + returned = m.foo + p.assert_called_once_with() + self.assertIsInstance(returned, MagicMock) + self.assertNotIsInstance(returned, PropertyMock) + + if __name__ == '__main__': unittest.main()