aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/unittest/test/testmock/testmock.py
diff options
context:
space:
mode:
authorvabr-g <vabr@google.com>2020-12-14 19:30:09 +0100
committerGitHub <noreply@github.com>2020-12-14 10:30:09 -0800
commitfdb9efce6ac211f973088eef508740c3fa2bd182 (patch)
tree9a109d25ccc8f22ed03710e3390fffc0b586674b /Lib/unittest/test/testmock/testmock.py
parent42c9f0fd0a5e67d4ae0022bfd7370cb9725a5b01 (diff)
downloadcpython-fdb9efce6ac211f973088eef508740c3fa2bd182.tar.gz
cpython-fdb9efce6ac211f973088eef508740c3fa2bd182.zip
bpo-41877: Check for misspelled speccing arguments (GH-23737)
patch, patch.object and create_autospec silently ignore misspelled arguments such as autospect, auto_spec and set_spec. This can lead to tests failing to check what they are supposed to check. This change adds a check causing a RuntimeError if the above functions get any of the above misspellings as arguments. It also adds a new argument, "unsafe", which can be set to True to disable this check. Also add "!r" to format specifiers in added error messages.
Diffstat (limited to 'Lib/unittest/test/testmock/testmock.py')
-rw-r--r--Lib/unittest/test/testmock/testmock.py52
1 files changed, 52 insertions, 0 deletions
diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/unittest/test/testmock/testmock.py
index 016905c3b90..e38f41e1d21 100644
--- a/Lib/unittest/test/testmock/testmock.py
+++ b/Lib/unittest/test/testmock/testmock.py
@@ -38,6 +38,12 @@ class Something(object):
def smeth(a, b, c, d=None): pass
+class Typos():
+ autospect = None
+ auto_spec = None
+ set_spec = None
+
+
def something(a): pass
@@ -2175,6 +2181,52 @@ class MockTest(unittest.TestCase):
self.assertEqual(obj.obj_with_bool_func.__bool__.call_count, 0)
+ def test_misspelled_arguments(self):
+ class Foo():
+ one = 'one'
+ # patch, patch.object and create_autospec need to check for misspelled
+ # arguments explicitly and throw a RuntimError if found.
+ with self.assertRaises(RuntimeError):
+ with patch(f'{__name__}.Something.meth', autospect=True): pass
+ with self.assertRaises(RuntimeError):
+ with patch.object(Foo, 'one', autospect=True): pass
+ with self.assertRaises(RuntimeError):
+ with patch(f'{__name__}.Something.meth', auto_spec=True): pass
+ with self.assertRaises(RuntimeError):
+ with patch.object(Foo, 'one', auto_spec=True): pass
+ with self.assertRaises(RuntimeError):
+ with patch(f'{__name__}.Something.meth', set_spec=True): pass
+ with self.assertRaises(RuntimeError):
+ with patch.object(Foo, 'one', set_spec=True): pass
+ with self.assertRaises(RuntimeError):
+ m = create_autospec(Foo, set_spec=True)
+ # patch.multiple, on the other hand, should flag misspelled arguments
+ # through an AttributeError, when trying to find the keys from kwargs
+ # as attributes on the target.
+ with self.assertRaises(AttributeError):
+ with patch.multiple(
+ f'{__name__}.Something', meth=DEFAULT, autospect=True): pass
+ with self.assertRaises(AttributeError):
+ with patch.multiple(
+ f'{__name__}.Something', meth=DEFAULT, auto_spec=True): pass
+ with self.assertRaises(AttributeError):
+ with patch.multiple(
+ f'{__name__}.Something', meth=DEFAULT, set_spec=True): pass
+
+ with patch(f'{__name__}.Something.meth', unsafe=True, autospect=True):
+ pass
+ with patch.object(Foo, 'one', unsafe=True, autospect=True): pass
+ with patch(f'{__name__}.Something.meth', unsafe=True, auto_spec=True):
+ pass
+ with patch.object(Foo, 'one', unsafe=True, auto_spec=True): pass
+ with patch(f'{__name__}.Something.meth', unsafe=True, set_spec=True):
+ pass
+ with patch.object(Foo, 'one', unsafe=True, set_spec=True): pass
+ m = create_autospec(Foo, set_spec=True, unsafe=True)
+ with patch.multiple(
+ f'{__name__}.Typos', autospect=True, set_spec=True, auto_spec=True):
+ pass
+
if __name__ == '__main__':
unittest.main()