summaryrefslogtreecommitdiff
path: root/mock/tests/testpatch.py
diff options
context:
space:
mode:
Diffstat (limited to 'mock/tests/testpatch.py')
-rw-r--r--mock/tests/testpatch.py191
1 files changed, 120 insertions, 71 deletions
diff --git a/mock/tests/testpatch.py b/mock/tests/testpatch.py
index bbd6d26..fbf4a53 100644
--- a/mock/tests/testpatch.py
+++ b/mock/tests/testpatch.py
@@ -4,24 +4,21 @@
import os
import sys
+from collections import OrderedDict
-import six
import unittest
-
from mock.tests import support
-from mock.tests.support import SomeClass, is_instance, uncache
+from mock.tests.support import SomeClass, is_instance
+from .support import uncache
from mock import (
- NonCallableMock, CallableMixin, patch, sentinel,
- MagicMock, Mock, NonCallableMagicMock,
+ NonCallableMock, sentinel,
+ MagicMock, Mock, NonCallableMagicMock, patch,
DEFAULT, call
)
-from mock.mock import _patch, _get_target
+from mock.mock import CallableMixin, _patch, _get_target
-builtin_string = '__builtin__'
-if six.PY3:
- builtin_string = 'builtins'
- unicode = str
+builtin_string = 'builtins'
PTModule = sys.modules[__name__]
MODNAME = '%s.PTModule' % __name__
@@ -109,6 +106,10 @@ class PatchTest(unittest.TestCase):
self.assertEqual(Something.attribute, sentinel.Original,
"patch not restored")
+ def test_patchobject_with_string_as_target(self):
+ msg = "'Something' must be the actual object to be patched, not a str"
+ with self.assertRaisesRegex(TypeError, msg):
+ patch.object('Something', 'do_something')
def test_patchobject_with_none(self):
class Something(object):
@@ -623,6 +624,13 @@ class PatchTest(unittest.TestCase):
self.assertEqual(foo.values, original)
+ def test_patch_dict_as_context_manager(self):
+ foo = {'a': 'b'}
+ with patch.dict(foo, a='c') as patched:
+ self.assertEqual(patched, {'a': 'c'})
+ self.assertEqual(foo, {'a': 'b'})
+
+
def test_name_preserved(self):
foo = {}
@@ -656,21 +664,15 @@ class PatchTest(unittest.TestCase):
test()
- def test_patch_dict_with_unicode(self):
- @patch.dict(u'os.environ', {'konrad_delong': 'some value'})
- def test():
- self.assertIn('konrad_delong', os.environ)
-
- test()
-
-
def test_patch_dict_decorator_resolution(self):
# bpo-35512: Ensure that patch with a string target resolves to
# the new dictionary during function call
original = support.target.copy()
+
@patch.dict('mock.tests.support.target', {'bar': 'BAR'})
def test():
self.assertEqual(support.target, {'foo': 'BAZ', 'bar': 'BAR'})
+
try:
support.target = {'foo': 'BAZ'}
test()
@@ -768,6 +770,14 @@ class PatchTest(unittest.TestCase):
self.assertEqual(d, original)
+ def test_patch_dict_stop_without_start(self):
+ d = {'foo': 'bar'}
+ original = d.copy()
+ patcher = patch.dict(d, [('spam', 'eggs')], clear=True)
+ self.assertEqual(patcher.stop(), False)
+ self.assertEqual(d, original)
+
+
def test_patch_dict_class_decorator(self):
this = self
d = {'spam': 'eggs'}
@@ -1329,7 +1339,7 @@ class PatchTest(unittest.TestCase):
try:
f = result['f']
foo = result['foo']
- self.assertEqual(set(result), {'f', 'foo'})
+ self.assertEqual(set(result), set(['f', 'foo']))
self.assertIs(Foo, original_foo)
self.assertIs(Foo.f, f)
@@ -1533,15 +1543,14 @@ class PatchTest(unittest.TestCase):
def test_patch_multiple_string_subclasses(self):
- for base in (str, unicode):
- Foo = type('Foo', (base,), {'fish': 'tasty'})
- foo = Foo()
- @patch.multiple(foo, fish='nearly gone')
- def test():
- self.assertEqual(foo.fish, 'nearly gone')
+ Foo = type('Foo', (str,), {'fish': 'tasty'})
+ foo = Foo()
+ @patch.multiple(foo, fish='nearly gone')
+ def test():
+ self.assertEqual(foo.fish, 'nearly gone')
- test()
- self.assertEqual(foo.fish, 'tasty')
+ test()
+ self.assertEqual(foo.fish, 'tasty')
@patch('mock.patch.TEST_PREFIX', 'foo')
@@ -1605,15 +1614,12 @@ class PatchTest(unittest.TestCase):
def test_patch_nested_autospec_repr(self):
- p = patch('mock.tests.support', autospec=True)
- m = p.start()
- try:
+ with patch('mock.tests.support', autospec=True) as m:
self.assertIn(" name='support.SomeClass.wibble()'",
repr(m.SomeClass.wibble()))
self.assertIn(" name='support.SomeClass().wibble()'",
repr(m.SomeClass().wibble()))
- finally:
- p.stop()
+
def test_mock_calls_with_patch(self):
@@ -1658,7 +1664,7 @@ class PatchTest(unittest.TestCase):
p1.stop()
self.assertEqual(squizz.squozz, 3)
- def test_patch_propogrates_exc_on_exit(self):
+ def test_patch_propagates_exc_on_exit(self):
class holder:
exc_info = None, None, None
@@ -1687,9 +1693,9 @@ class PatchTest(unittest.TestCase):
self.assertIs(holder.exc_info[0], RuntimeError)
self.assertIsNotNone(holder.exc_info[1],
- 'exception value not propgated')
+ 'exception value not propagated')
self.assertIsNotNone(holder.exc_info[2],
- 'exception traceback not propgated')
+ 'exception traceback not propagated')
def test_create_and_specs(self):
@@ -1793,32 +1799,6 @@ class PatchTest(unittest.TestCase):
patched()
self.assertIs(os.path, path)
-
- def test_wrapped_patch(self):
- decorated = patch('sys.modules')(function)
- self.assertIs(decorated.__wrapped__, function)
-
-
- def test_wrapped_several_times_patch(self):
- decorated = patch('sys.modules')(function)
- decorated = patch('sys.modules')(decorated)
- self.assertIs(decorated.__wrapped__, function)
-
-
- def test_wrapped_patch_object(self):
- decorated = patch.object(sys, 'modules')(function)
- self.assertIs(decorated.__wrapped__, function)
-
-
- def test_wrapped_patch_dict(self):
- decorated = patch.dict('sys.modules')(function)
- self.assertIs(decorated.__wrapped__, function)
-
-
- def test_wrapped_patch_multiple(self):
- decorated = patch.multiple('sys', modules={})(function)
- self.assertIs(decorated.__wrapped__, function)
-
def test_stopall_lifo(self):
stopped = []
class thing(object):
@@ -1836,6 +1816,56 @@ class PatchTest(unittest.TestCase):
self.assertEqual(stopped, ["three", "two", "one"])
+ def test_patch_dict_stopall(self):
+ dic1 = {}
+ dic2 = {1: 'a'}
+ dic3 = {1: 'A', 2: 'B'}
+ origdic1 = dic1.copy()
+ origdic2 = dic2.copy()
+ origdic3 = dic3.copy()
+ patch.dict(dic1, {1: 'I', 2: 'II'}).start()
+ patch.dict(dic2, {2: 'b'}).start()
+
+ @patch.dict(dic3)
+ def patched():
+ del dic3[1]
+
+ patched()
+ self.assertNotEqual(dic1, origdic1)
+ self.assertNotEqual(dic2, origdic2)
+ self.assertEqual(dic3, origdic3)
+
+ patch.stopall()
+
+ self.assertEqual(dic1, origdic1)
+ self.assertEqual(dic2, origdic2)
+ self.assertEqual(dic3, origdic3)
+
+
+ def test_patch_and_patch_dict_stopall(self):
+ original_unlink = os.unlink
+ original_chdir = os.chdir
+ dic1 = {}
+ dic2 = {1: 'A', 2: 'B'}
+ origdic1 = dic1.copy()
+ origdic2 = dic2.copy()
+
+ patch('os.unlink', something).start()
+ patch('os.chdir', something_else).start()
+ patch.dict(dic1, {1: 'I', 2: 'II'}).start()
+ patch.dict(dic2).start()
+ del dic2[1]
+
+ self.assertIsNot(os.unlink, original_unlink)
+ self.assertIsNot(os.chdir, original_chdir)
+ self.assertNotEqual(dic1, origdic1)
+ self.assertNotEqual(dic2, origdic2)
+ patch.stopall()
+ self.assertIs(os.unlink, original_unlink)
+ self.assertIs(os.chdir, original_chdir)
+ self.assertEqual(dic1, origdic1)
+ self.assertEqual(dic2, origdic2)
+
def test_special_attrs(self):
def foo(x=0):
@@ -1851,22 +1881,40 @@ class PatchTest(unittest.TestCase):
with patch.object(foo, '__module__', "testpatch2"):
self.assertEqual(foo.__module__, "testpatch2")
- self.assertEqual(foo.__module__, __name__)
+ self.assertEqual(foo.__module__, 'mock.tests.testpatch')
+
+ with patch.object(foo, '__annotations__', dict([('s', 1, )])):
+ self.assertEqual(foo.__annotations__, dict([('s', 1, )]))
+ self.assertEqual(foo.__annotations__, dict())
+
+ def foo(*a, x=0):
+ return x
+ with patch.object(foo, '__kwdefaults__', dict([('x', 1, )])):
+ self.assertEqual(foo(), 1)
+ self.assertEqual(foo(), 0)
- if hasattr(self.test_special_attrs, '__annotations__'):
- with patch.object(foo, '__annotations__', dict([('s', 1, )])):
- self.assertEqual(foo.__annotations__, dict([('s', 1, )]))
- self.assertEqual(foo.__annotations__, dict())
+ def test_patch_orderdict(self):
+ foo = OrderedDict()
+ foo['a'] = object()
+ foo['b'] = 'python'
- if hasattr(self.test_special_attrs, '__kwdefaults__'):
- foo = eval("lambda *a, x=0: x")
- with patch.object(foo, '__kwdefaults__', dict([('x', 1, )])):
- self.assertEqual(foo(), 1)
- self.assertEqual(foo(), 0)
+ original = foo.copy()
+ update_values = list(zip('cdefghijklmnopqrstuvwxyz', range(26)))
+ patched_values = list(foo.items()) + update_values
+ with patch.dict(foo, OrderedDict(update_values)):
+ self.assertEqual(list(foo.items()), patched_values)
+
+ self.assertEqual(foo, original)
+
+ with patch.dict(foo, update_values):
+ self.assertEqual(list(foo.items()), patched_values)
+
+ self.assertEqual(foo, original)
def test_dotted_but_module_not_loaded(self):
# This exercises the AttributeError branch of _dot_lookup.
+
# make sure it's there
import mock.tests.support
# now make sure it's not:
@@ -1875,6 +1923,7 @@ class PatchTest(unittest.TestCase):
del sys.modules['mock.tests']
del sys.modules['mock.mock']
del sys.modules['mock']
+
# now make sure we can patch based on a dotted path:
@patch('mock.tests.support.X')
def test(mock):