diff options
author | Michael Foord <michael@voidspace.org.uk> | 2012-03-25 17:57:58 (GMT) |
---|---|---|
committer | Michael Foord <michael@voidspace.org.uk> | 2012-03-25 17:57:58 (GMT) |
commit | 50a8c0ef5d6c7ae213d86940cc842c0f73fb273a (patch) | |
tree | 4df0c729656f233d927e0c9663fd716ca1b4bbe2 /Lib/unittest/test | |
parent | a3eabb6f8eb0c8f9e5c3d2ecd6f60a96567624b3 (diff) | |
download | cpython-50a8c0ef5d6c7ae213d86940cc842c0f73fb273a.zip cpython-50a8c0ef5d6c7ae213d86940cc842c0f73fb273a.tar.gz cpython-50a8c0ef5d6c7ae213d86940cc842c0f73fb273a.tar.bz2 |
Support subclassing unittest.mock._patch and fix various obscure bugs around patcher spec arguments
Diffstat (limited to 'Lib/unittest/test')
-rw-r--r-- | Lib/unittest/test/testmock/testpatch.py | 109 |
1 files changed, 102 insertions, 7 deletions
diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/unittest/test/testmock/testpatch.py index fccad31..204a30a 100644 --- a/Lib/unittest/test/testmock/testpatch.py +++ b/Lib/unittest/test/testmock/testpatch.py @@ -11,14 +11,15 @@ from unittest.test.testmock.support import SomeClass, is_instance from unittest.mock import ( NonCallableMock, CallableMixin, patch, sentinel, - MagicMock, Mock, NonCallableMagicMock, patch, - DEFAULT, call + MagicMock, Mock, NonCallableMagicMock, patch, _patch, + DEFAULT, call, _get_target ) builtin_string = 'builtins' PTModule = sys.modules[__name__] +MODNAME = '%s.PTModule' % __name__ def _get_proxy(obj, get_only=True): @@ -724,8 +725,8 @@ class PatchTest(unittest.TestCase): patcher = patch('%s.something' % __name__) self.assertIs(something, original) mock = patcher.start() - self.assertIsNot(mock, original) try: + self.assertIsNot(mock, original) self.assertIs(something, mock) finally: patcher.stop() @@ -744,8 +745,8 @@ class PatchTest(unittest.TestCase): patcher = patch.object(PTModule, 'something', 'foo') self.assertIs(something, original) replaced = patcher.start() - self.assertEqual(replaced, 'foo') try: + self.assertEqual(replaced, 'foo') self.assertIs(something, replaced) finally: patcher.stop() @@ -759,9 +760,10 @@ class PatchTest(unittest.TestCase): self.assertEqual(d, original) patcher.start() - self.assertEqual(d, {'spam': 'eggs'}) - - patcher.stop() + try: + self.assertEqual(d, {'spam': 'eggs'}) + finally: + patcher.stop() self.assertEqual(d, original) @@ -1647,6 +1649,99 @@ class PatchTest(unittest.TestCase): self.assertEqual(squizz.squozz, 3) + def test_patch_propogrates_exc_on_exit(self): + class holder: + exc_info = None, None, None + + class custom_patch(_patch): + def __exit__(self, etype=None, val=None, tb=None): + _patch.__exit__(self, etype, val, tb) + holder.exc_info = etype, val, tb + stop = __exit__ + + def with_custom_patch(target): + getter, attribute = _get_target(target) + return custom_patch( + getter, attribute, DEFAULT, None, False, None, + None, None, {} + ) + + @with_custom_patch('squizz.squozz') + def test(mock): + raise RuntimeError + + self.assertRaises(RuntimeError, test) + self.assertIs(holder.exc_info[0], RuntimeError) + self.assertIsNotNone(holder.exc_info[1], + 'exception value not propgated') + self.assertIsNotNone(holder.exc_info[2], + 'exception traceback not propgated') + + + def test_create_and_specs(self): + for kwarg in ('spec', 'spec_set', 'autospec'): + p = patch('%s.doesnotexist' % __name__, create=True, + **{kwarg: True}) + self.assertRaises(TypeError, p.start) + self.assertRaises(NameError, lambda: doesnotexist) + + # check that spec with create is innocuous if the original exists + p = patch(MODNAME, create=True, **{kwarg: True}) + p.start() + p.stop() + + + def test_multiple_specs(self): + original = PTModule + for kwarg in ('spec', 'spec_set'): + p = patch(MODNAME, autospec=0, **{kwarg: 0}) + self.assertRaises(TypeError, p.start) + self.assertIs(PTModule, original) + + for kwarg in ('spec', 'autospec'): + p = patch(MODNAME, spec_set=0, **{kwarg: 0}) + self.assertRaises(TypeError, p.start) + self.assertIs(PTModule, original) + + for kwarg in ('spec_set', 'autospec'): + p = patch(MODNAME, spec=0, **{kwarg: 0}) + self.assertRaises(TypeError, p.start) + self.assertIs(PTModule, original) + + + def test_specs_false_instead_of_none(self): + p = patch(MODNAME, spec=False, spec_set=False, autospec=False) + mock = p.start() + try: + # no spec should have been set, so attribute access should not fail + mock.does_not_exist + mock.does_not_exist = 3 + finally: + p.stop() + + + def test_falsey_spec(self): + for kwarg in ('spec', 'autospec', 'spec_set'): + p = patch(MODNAME, **{kwarg: 0}) + m = p.start() + try: + self.assertRaises(AttributeError, getattr, m, 'doesnotexit') + finally: + p.stop() + + + def test_spec_set_true(self): + for kwarg in ('spec', 'autospec'): + p = patch(MODNAME, spec_set=True, **{kwarg: True}) + m = p.start() + try: + self.assertRaises(AttributeError, setattr, m, + 'doesnotexist', 'something') + self.assertRaises(AttributeError, getattr, m, 'doesnotexist') + finally: + p.stop() + + if __name__ == '__main__': unittest.main() |