summaryrefslogtreecommitdiff
path: root/Lib/unittest/test/testmock/testpatch.py
diff options
context:
space:
mode:
authorChris Withers <chris@withers.org>2019-05-01 23:04:04 +0100
committerGitHub <noreply@github.com>2019-05-01 23:04:04 +0100
commitadbf178e49113b2de0042e86a1228560475a65c5 (patch)
tree871ac21aec993e310f915cf2781909282a7a03e9 /Lib/unittest/test/testmock/testpatch.py
parentb7378d77289c911ca6a0c0afaf513879002df7d5 (diff)
downloadcpython-git-adbf178e49113b2de0042e86a1228560475a65c5.tar.gz
Mock 100% coverage (GH-13045)
This was achieved by: * moving many pass statements in tests onto their own lines, so they pass line coverage and can match an easy ignore pattern if branch coverage is added later. * removing code that cannot be reached. * removing long-disabled tests. * removing unused code. * adding tests for uncovered code It turned out that removing `if __name__ == '__main__'` blocks that run unittest.main() at the bottom of test files was surprisingly contentious, so they remain and can be filtered out with an appropriate .coveragerc.
Diffstat (limited to 'Lib/unittest/test/testmock/testpatch.py')
-rw-r--r--Lib/unittest/test/testmock/testpatch.py164
1 files changed, 60 insertions, 104 deletions
diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/unittest/test/testmock/testpatch.py
index e5abd9bda4..3295c5b242 100644
--- a/Lib/unittest/test/testmock/testpatch.py
+++ b/Lib/unittest/test/testmock/testpatch.py
@@ -43,31 +43,24 @@ something_else = sentinel.SomethingElse
class Foo(object):
- def __init__(self, a):
- pass
- def f(self, a):
- pass
- def g(self):
- pass
+ def __init__(self, a): pass
+ def f(self, a): pass
+ def g(self): pass
foo = 'bar'
@staticmethod
- def static_method():
- return 24
+ def static_method(): pass
@classmethod
- def class_method(cls):
- return 42
+ def class_method(cls): pass
class Bar(object):
- def a(self):
- pass
+ def a(self): pass
foo_name = '%s.Foo' % __name__
-def function(a, b=Foo):
- pass
+def function(a, b=Foo): pass
class Container(object):
@@ -370,31 +363,19 @@ class PatchTest(unittest.TestCase):
def test_patch_wont_create_by_default(self):
- try:
+ with self.assertRaises(AttributeError):
@patch('%s.frooble' % builtin_string, sentinel.Frooble)
- def test():
- self.assertEqual(frooble, sentinel.Frooble)
+ def test(): pass
test()
- except AttributeError:
- pass
- else:
- self.fail('Patching non existent attributes should fail')
-
self.assertRaises(NameError, lambda: frooble)
def test_patchobject_wont_create_by_default(self):
- try:
+ with self.assertRaises(AttributeError):
@patch.object(SomeClass, 'ord', sentinel.Frooble)
- def test():
- self.fail('Patching non existent attributes should fail')
-
+ def test(): pass
test()
- except AttributeError:
- pass
- else:
- self.fail('Patching non existent attributes should fail')
self.assertFalse(hasattr(SomeClass, 'ord'))
@@ -484,6 +465,9 @@ class PatchTest(unittest.TestCase):
attribute = sentinel.Original
class Foo(object):
+
+ test_class_attr = 'whatever'
+
def test_method(other_self, mock_something):
self.assertEqual(PTModule.something, mock_something,
"unpatched")
@@ -642,8 +626,7 @@ class PatchTest(unittest.TestCase):
@patch('%s.SomeClass' % __name__, object(), autospec=True)
@patch.object(SomeClass, object())
@patch.dict(foo)
- def some_name():
- pass
+ def some_name(): pass
self.assertEqual(some_name.__name__, 'some_name')
@@ -654,12 +637,9 @@ class PatchTest(unittest.TestCase):
@patch.dict(foo, {'a': 'b'})
def test():
raise NameError('Konrad')
- try:
+
+ with self.assertRaises(NameError):
test()
- except NameError:
- pass
- else:
- self.fail('NameError not raised by test')
self.assertEqual(foo, {})
@@ -689,49 +669,6 @@ class PatchTest(unittest.TestCase):
support.target = original
- def test_patch_descriptor(self):
- # would be some effort to fix this - we could special case the
- # builtin descriptors: classmethod, property, staticmethod
- return
- class Nothing(object):
- foo = None
-
- class Something(object):
- foo = {}
-
- @patch.object(Nothing, 'foo', 2)
- @classmethod
- def klass(cls):
- self.assertIs(cls, Something)
-
- @patch.object(Nothing, 'foo', 2)
- @staticmethod
- def static(arg):
- return arg
-
- @patch.dict(foo)
- @classmethod
- def klass_dict(cls):
- self.assertIs(cls, Something)
-
- @patch.dict(foo)
- @staticmethod
- def static_dict(arg):
- return arg
-
- # these will raise exceptions if patching descriptors is broken
- self.assertEqual(Something.static('f00'), 'f00')
- Something.klass()
- self.assertEqual(Something.static_dict('f00'), 'f00')
- Something.klass_dict()
-
- something = Something()
- self.assertEqual(something.static('f00'), 'f00')
- something.klass()
- self.assertEqual(something.static_dict('f00'), 'f00')
- something.klass_dict()
-
-
def test_patch_spec_set(self):
@patch('%s.SomeClass' % __name__, spec=SomeClass, spec_set=True)
def test(MockClass):
@@ -931,17 +868,13 @@ class PatchTest(unittest.TestCase):
def test_autospec(self):
class Boo(object):
- def __init__(self, a):
- pass
- def f(self, a):
- pass
- def g(self):
- pass
+ def __init__(self, a): pass
+ def f(self, a): pass
+ def g(self): pass
foo = 'bar'
class Bar(object):
- def a(self):
- pass
+ def a(self): pass
def _test(mock):
mock(1)
@@ -1488,20 +1421,17 @@ class PatchTest(unittest.TestCase):
@patch.object(Foo, 'g', 1)
@patch.object(Foo, 'missing', 1)
@patch.object(Foo, 'f', 1)
- def thing1():
- pass
+ def thing1(): pass
@patch.object(Foo, 'missing', 1)
@patch.object(Foo, 'g', 1)
@patch.object(Foo, 'f', 1)
- def thing2():
- pass
+ def thing2(): pass
@patch.object(Foo, 'g', 1)
@patch.object(Foo, 'f', 1)
@patch.object(Foo, 'missing', 1)
- def thing3():
- pass
+ def thing3(): pass
for func in thing1, thing2, thing3:
self.assertRaises(AttributeError, func)
@@ -1520,20 +1450,17 @@ class PatchTest(unittest.TestCase):
@patch.object(Foo, 'g', 1)
@patch.object(Foo, 'foo', new_callable=crasher)
@patch.object(Foo, 'f', 1)
- def thing1():
- pass
+ def thing1(): pass
@patch.object(Foo, 'foo', new_callable=crasher)
@patch.object(Foo, 'g', 1)
@patch.object(Foo, 'f', 1)
- def thing2():
- pass
+ def thing2(): pass
@patch.object(Foo, 'g', 1)
@patch.object(Foo, 'f', 1)
@patch.object(Foo, 'foo', new_callable=crasher)
- def thing3():
- pass
+ def thing3(): pass
for func in thing1, thing2, thing3:
self.assertRaises(NameError, func)
@@ -1559,8 +1486,7 @@ class PatchTest(unittest.TestCase):
patcher.additional_patchers = additionals
@patcher
- def func():
- pass
+ def func(): pass
self.assertRaises(AttributeError, func)
self.assertEqual(Foo.f, original_f)
@@ -1588,8 +1514,7 @@ class PatchTest(unittest.TestCase):
patcher.additional_patchers = additionals
@patcher
- def func():
- pass
+ def func(): pass
self.assertRaises(NameError, func)
self.assertEqual(Foo.f, original_f)
@@ -1898,5 +1823,36 @@ class PatchTest(unittest.TestCase):
self.assertEqual(foo(), 1)
self.assertEqual(foo(), 0)
+ def test_dotted_but_module_not_loaded(self):
+ # This exercises the AttributeError branch of _dot_lookup.
+
+ # make sure it's there
+ import unittest.test.testmock.support
+ # now make sure it's not:
+ with patch.dict('sys.modules'):
+ del sys.modules['unittest.test.testmock.support']
+ del sys.modules['unittest.test.testmock']
+ del sys.modules['unittest.test']
+ del sys.modules['unittest']
+
+ # now make sure we can patch based on a dotted path:
+ @patch('unittest.test.testmock.support.X')
+ def test(mock):
+ pass
+ test()
+
+
+ def test_invalid_target(self):
+ with self.assertRaises(TypeError):
+ patch('')
+
+
+ def test_cant_set_kwargs_when_passing_a_mock(self):
+ @patch('unittest.test.testmock.support.X', new=object(), x=1)
+ def test(): pass
+ with self.assertRaises(TypeError):
+ test()
+
+
if __name__ == '__main__':
unittest.main()