summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Foord <michael@voidspace.org.uk>2012-04-13 17:16:54 +0100
committerMichael Foord <michael@voidspace.org.uk>2012-04-13 17:16:54 +0100
commit7e44aecbd98ce6e4718c81a12418505c2172fcc7 (patch)
tree3d472c2747dcfdbd46b81418a6ae8ca13a666597
parent021c8f04ba6dd92955fe02b988f29049a3540212 (diff)
downloadmock-7e44aecbd98ce6e4718c81a12418505c2172fcc7.tar.gz
create_autospec now works with attributes that can't be fetched
-rw-r--r--docs/changelog.txt4
-rw-r--r--mock.py5
-rw-r--r--tests/testhelpers.py23
3 files changed, 31 insertions, 1 deletions
diff --git a/docs/changelog.txt b/docs/changelog.txt
index b42bc7d..ad441c9 100644
--- a/docs/changelog.txt
+++ b/docs/changelog.txt
@@ -8,6 +8,10 @@ CHANGELOG
2012/XX/XX Version 1.0.0 alpha 2
--------------------------------
+* `PropertyMock` attributes are now standard `MagicMocks`
+* `create_autospec` works with attributes present in results of `dir` that
+ can't be fetched from the object's class
+
2012/03/25 Version 1.0.0 alpha 1
--------------------------------
diff --git a/mock.py b/mock.py
index cf38238..e69a65c 100644
--- a/mock.py
+++ b/mock.py
@@ -2166,7 +2166,10 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
# XXXX what about attributes that raise exceptions on being fetched
# we could be resilient against it, or catch and propagate the
# exception when the attribute is fetched from the mock
- original = getattr(spec, entry)
+ try:
+ original = getattr(spec, entry)
+ except AttributeError:
+ continue
kwargs = {'spec': original}
if spec_set:
diff --git a/tests/testhelpers.py b/tests/testhelpers.py
index b92f511..6a7d68b 100644
--- a/tests/testhelpers.py
+++ b/tests/testhelpers.py
@@ -691,6 +691,29 @@ class SpecSignatureTest(unittest2.TestCase):
mock.assert_called_with(4, 5)
+ def test_skip_attributeerrors(self):
+ class Raiser(object):
+ def __get__(self, obj, type=None):
+ if obj is None:
+ raise AttributeError('Can only be accessed via an instance')
+
+ class RaiserClass(object):
+ raiser = Raiser()
+
+ @staticmethod
+ def existing(a, b):
+ return a + b
+
+ s = create_autospec(RaiserClass)
+ self.assertRaises(TypeError, lambda x: s.existing(1, 2, 3))
+ s.existing(1, 2)
+ self.assertRaises(AttributeError, lambda: s.nonexisting)
+
+ # check we can fetch the raiser attribute and it has no spec
+ obj = s.raiser
+ obj.foo, obj.bar
+
+
@unittest2.skipIf(inPy3k, 'no old style classes in Python 3')
def test_signature_old_style_class(self):
class Foo: