mirror of
https://github.com/python/cpython.git
synced 2025-08-03 00:23:06 +00:00
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.
This commit is contained in:
parent
b7378d7728
commit
adbf178e49
9 changed files with 263 additions and 317 deletions
|
@ -63,10 +63,7 @@ def _get_signature_object(func, as_instance, eat_self):
|
||||||
"""
|
"""
|
||||||
if isinstance(func, type) and not as_instance:
|
if isinstance(func, type) and not as_instance:
|
||||||
# If it's a type and should be modelled as a type, use __init__.
|
# If it's a type and should be modelled as a type, use __init__.
|
||||||
try:
|
func = func.__init__
|
||||||
func = func.__init__
|
|
||||||
except AttributeError:
|
|
||||||
return None
|
|
||||||
# Skip the `self` argument in __init__
|
# Skip the `self` argument in __init__
|
||||||
eat_self = True
|
eat_self = True
|
||||||
elif not isinstance(func, FunctionTypes):
|
elif not isinstance(func, FunctionTypes):
|
||||||
|
@ -147,8 +144,6 @@ def _set_signature(mock, original, instance=False):
|
||||||
# creates a function with signature (*args, **kwargs) that delegates to a
|
# creates a function with signature (*args, **kwargs) that delegates to a
|
||||||
# mock. It still does signature checking by calling a lambda with the same
|
# mock. It still does signature checking by calling a lambda with the same
|
||||||
# signature as the original.
|
# signature as the original.
|
||||||
if not _callable(original):
|
|
||||||
return
|
|
||||||
|
|
||||||
skipfirst = isinstance(original, type)
|
skipfirst = isinstance(original, type)
|
||||||
result = _get_signature_object(original, instance, skipfirst)
|
result = _get_signature_object(original, instance, skipfirst)
|
||||||
|
@ -175,10 +170,6 @@ def _set_signature(mock, original, instance=False):
|
||||||
def _setup_func(funcopy, mock, sig):
|
def _setup_func(funcopy, mock, sig):
|
||||||
funcopy.mock = mock
|
funcopy.mock = mock
|
||||||
|
|
||||||
# can't use isinstance with mocks
|
|
||||||
if not _is_instance_mock(mock):
|
|
||||||
return
|
|
||||||
|
|
||||||
def assert_called_with(*args, **kwargs):
|
def assert_called_with(*args, **kwargs):
|
||||||
return mock.assert_called_with(*args, **kwargs)
|
return mock.assert_called_with(*args, **kwargs)
|
||||||
def assert_called(*args, **kwargs):
|
def assert_called(*args, **kwargs):
|
||||||
|
@ -263,12 +254,6 @@ _missing = sentinel.MISSING
|
||||||
_deleted = sentinel.DELETED
|
_deleted = sentinel.DELETED
|
||||||
|
|
||||||
|
|
||||||
def _copy(value):
|
|
||||||
if type(value) in (dict, list, tuple, set):
|
|
||||||
return type(value)(value)
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
_allowed_names = {
|
_allowed_names = {
|
||||||
'return_value', '_mock_return_value', 'side_effect',
|
'return_value', '_mock_return_value', 'side_effect',
|
||||||
'_mock_side_effect', '_mock_parent', '_mock_new_parent',
|
'_mock_side_effect', '_mock_parent', '_mock_new_parent',
|
||||||
|
@ -351,8 +336,6 @@ def _check_and_set_parent(parent, value, name, new_name):
|
||||||
class _MockIter(object):
|
class _MockIter(object):
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
self.obj = iter(obj)
|
self.obj = iter(obj)
|
||||||
def __iter__(self):
|
|
||||||
return self
|
|
||||||
def __next__(self):
|
def __next__(self):
|
||||||
return next(self.obj)
|
return next(self.obj)
|
||||||
|
|
||||||
|
@ -452,7 +435,7 @@ class NonCallableMock(Base):
|
||||||
if isinstance(spec, type):
|
if isinstance(spec, type):
|
||||||
_spec_class = spec
|
_spec_class = spec
|
||||||
else:
|
else:
|
||||||
_spec_class = _get_class(spec)
|
_spec_class = type(spec)
|
||||||
res = _get_signature_object(spec,
|
res = _get_signature_object(spec,
|
||||||
_spec_as_instance, _eat_self)
|
_spec_as_instance, _eat_self)
|
||||||
_spec_signature = res and res[1]
|
_spec_signature = res and res[1]
|
||||||
|
@ -624,7 +607,7 @@ class NonCallableMock(Base):
|
||||||
dot = '.'
|
dot = '.'
|
||||||
if _name_list == ['()']:
|
if _name_list == ['()']:
|
||||||
dot = ''
|
dot = ''
|
||||||
seen = set()
|
|
||||||
while _parent is not None:
|
while _parent is not None:
|
||||||
last = _parent
|
last = _parent
|
||||||
|
|
||||||
|
@ -635,11 +618,6 @@ class NonCallableMock(Base):
|
||||||
|
|
||||||
_parent = _parent._mock_new_parent
|
_parent = _parent._mock_new_parent
|
||||||
|
|
||||||
# use ids here so as not to call __hash__ on the mocks
|
|
||||||
if id(_parent) in seen:
|
|
||||||
break
|
|
||||||
seen.add(id(_parent))
|
|
||||||
|
|
||||||
_name_list = list(reversed(_name_list))
|
_name_list = list(reversed(_name_list))
|
||||||
_first = last._mock_name or 'mock'
|
_first = last._mock_name or 'mock'
|
||||||
if len(_name_list) > 1:
|
if len(_name_list) > 1:
|
||||||
|
@ -753,8 +731,6 @@ class NonCallableMock(Base):
|
||||||
message = 'expected call not found.\nExpected: %s\nActual: %s'
|
message = 'expected call not found.\nExpected: %s\nActual: %s'
|
||||||
expected_string = self._format_mock_call_signature(args, kwargs)
|
expected_string = self._format_mock_call_signature(args, kwargs)
|
||||||
call_args = self.call_args
|
call_args = self.call_args
|
||||||
if len(call_args) == 3:
|
|
||||||
call_args = call_args[1:]
|
|
||||||
actual_string = self._format_mock_call_signature(*call_args)
|
actual_string = self._format_mock_call_signature(*call_args)
|
||||||
return message % (expected_string, actual_string)
|
return message % (expected_string, actual_string)
|
||||||
|
|
||||||
|
@ -992,8 +968,6 @@ class CallableMixin(Base):
|
||||||
self.call_args = _call
|
self.call_args = _call
|
||||||
self.call_args_list.append(_call)
|
self.call_args_list.append(_call)
|
||||||
|
|
||||||
seen = set()
|
|
||||||
|
|
||||||
# initial stuff for method_calls:
|
# initial stuff for method_calls:
|
||||||
do_method_calls = self._mock_parent is not None
|
do_method_calls = self._mock_parent is not None
|
||||||
method_call_name = self._mock_name
|
method_call_name = self._mock_name
|
||||||
|
@ -1029,13 +1003,6 @@ class CallableMixin(Base):
|
||||||
# follow the parental chain:
|
# follow the parental chain:
|
||||||
_new_parent = _new_parent._mock_new_parent
|
_new_parent = _new_parent._mock_new_parent
|
||||||
|
|
||||||
# check we're not in an infinite loop:
|
|
||||||
# ( use ids here so as not to call __hash__ on the mocks)
|
|
||||||
_new_parent_id = id(_new_parent)
|
|
||||||
if _new_parent_id in seen:
|
|
||||||
break
|
|
||||||
seen.add(_new_parent_id)
|
|
||||||
|
|
||||||
effect = self.side_effect
|
effect = self.side_effect
|
||||||
if effect is not None:
|
if effect is not None:
|
||||||
if _is_exception(effect):
|
if _is_exception(effect):
|
||||||
|
@ -1858,12 +1825,7 @@ def _set_return_value(mock, method, name):
|
||||||
|
|
||||||
return_calulator = _calculate_return_value.get(name)
|
return_calulator = _calculate_return_value.get(name)
|
||||||
if return_calulator is not None:
|
if return_calulator is not None:
|
||||||
try:
|
return_value = return_calulator(mock)
|
||||||
return_value = return_calulator(mock)
|
|
||||||
except AttributeError:
|
|
||||||
# XXXX why do we return AttributeError here?
|
|
||||||
# set it as a side_effect instead?
|
|
||||||
return_value = AttributeError(name)
|
|
||||||
method.return_value = return_value
|
method.return_value = return_value
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -1943,10 +1905,6 @@ class MagicProxy(object):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
|
||||||
m = self.create_mock()
|
|
||||||
return m(*args, **kwargs)
|
|
||||||
|
|
||||||
def create_mock(self):
|
def create_mock(self):
|
||||||
entry = self.name
|
entry = self.name
|
||||||
parent = self.parent
|
parent = self.parent
|
||||||
|
@ -2330,19 +2288,10 @@ def _must_skip(spec, entry, is_type):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# shouldn't get here unless function is a dynamically provided attribute
|
# function is a dynamically provided attribute
|
||||||
# XXXX untested behaviour
|
|
||||||
return is_type
|
return is_type
|
||||||
|
|
||||||
|
|
||||||
def _get_class(obj):
|
|
||||||
try:
|
|
||||||
return obj.__class__
|
|
||||||
except AttributeError:
|
|
||||||
# it is possible for objects to have no __class__
|
|
||||||
return type(obj)
|
|
||||||
|
|
||||||
|
|
||||||
class _SpecState(object):
|
class _SpecState(object):
|
||||||
|
|
||||||
def __init__(self, spec, spec_set=False, parent=None,
|
def __init__(self, spec, spec_set=False, parent=None,
|
||||||
|
|
|
@ -9,8 +9,7 @@ def is_instance(obj, klass):
|
||||||
class SomeClass(object):
|
class SomeClass(object):
|
||||||
class_attribute = None
|
class_attribute = None
|
||||||
|
|
||||||
def wibble(self):
|
def wibble(self): pass
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class X(object):
|
class X(object):
|
||||||
|
|
|
@ -98,8 +98,7 @@ class TestCallable(unittest.TestCase):
|
||||||
|
|
||||||
def test_patch_spec_callable_class(self):
|
def test_patch_spec_callable_class(self):
|
||||||
class CallableX(X):
|
class CallableX(X):
|
||||||
def __call__(self):
|
def __call__(self): pass
|
||||||
pass
|
|
||||||
|
|
||||||
class Sub(CallableX):
|
class Sub(CallableX):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -12,12 +12,9 @@ from datetime import datetime
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
class SomeClass(object):
|
class SomeClass(object):
|
||||||
def one(self, a, b):
|
def one(self, a, b): pass
|
||||||
pass
|
def two(self): pass
|
||||||
def two(self):
|
def three(self, a=None): pass
|
||||||
pass
|
|
||||||
def three(self, a=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,12 +45,9 @@ class AnyTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_any_mock_calls_comparison_order(self):
|
def test_any_mock_calls_comparison_order(self):
|
||||||
mock = Mock()
|
mock = Mock()
|
||||||
d = datetime.now()
|
|
||||||
class Foo(object):
|
class Foo(object):
|
||||||
def __eq__(self, other):
|
def __eq__(self, other): pass
|
||||||
return False
|
def __ne__(self, other): pass
|
||||||
def __ne__(self, other):
|
|
||||||
return True
|
|
||||||
|
|
||||||
for d in datetime.now(), Foo():
|
for d in datetime.now(), Foo():
|
||||||
mock.reset_mock()
|
mock.reset_mock()
|
||||||
|
@ -378,8 +372,7 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
def test_create_autospec_return_value(self):
|
def test_create_autospec_return_value(self):
|
||||||
def f():
|
def f(): pass
|
||||||
pass
|
|
||||||
mock = create_autospec(f, return_value='foo')
|
mock = create_autospec(f, return_value='foo')
|
||||||
self.assertEqual(mock(), 'foo')
|
self.assertEqual(mock(), 'foo')
|
||||||
|
|
||||||
|
@ -399,8 +392,7 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_mocking_unbound_methods(self):
|
def test_mocking_unbound_methods(self):
|
||||||
class Foo(object):
|
class Foo(object):
|
||||||
def foo(self, foo):
|
def foo(self, foo): pass
|
||||||
pass
|
|
||||||
p = patch.object(Foo, 'foo')
|
p = patch.object(Foo, 'foo')
|
||||||
mock_foo = p.start()
|
mock_foo = p.start()
|
||||||
Foo().foo(1)
|
Foo().foo(1)
|
||||||
|
@ -408,24 +400,6 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
mock_foo.assert_called_with(1)
|
mock_foo.assert_called_with(1)
|
||||||
|
|
||||||
|
|
||||||
def test_create_autospec_unbound_methods(self):
|
|
||||||
# see mock issue 128
|
|
||||||
# this is expected to fail until the issue is fixed
|
|
||||||
return
|
|
||||||
class Foo(object):
|
|
||||||
def foo(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
klass = create_autospec(Foo)
|
|
||||||
instance = klass()
|
|
||||||
self.assertRaises(TypeError, instance.foo, 1)
|
|
||||||
|
|
||||||
# Note: no type checking on the "self" parameter
|
|
||||||
klass.foo(1)
|
|
||||||
klass.foo.assert_called_with(1)
|
|
||||||
self.assertRaises(TypeError, klass.foo)
|
|
||||||
|
|
||||||
|
|
||||||
def test_create_autospec_keyword_arguments(self):
|
def test_create_autospec_keyword_arguments(self):
|
||||||
class Foo(object):
|
class Foo(object):
|
||||||
a = 3
|
a = 3
|
||||||
|
@ -434,8 +408,7 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
def test_create_autospec_keyword_only_arguments(self):
|
def test_create_autospec_keyword_only_arguments(self):
|
||||||
def foo(a, *, b=None):
|
def foo(a, *, b=None): pass
|
||||||
pass
|
|
||||||
|
|
||||||
m = create_autospec(foo)
|
m = create_autospec(foo)
|
||||||
m(1)
|
m(1)
|
||||||
|
@ -448,8 +421,7 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_function_as_instance_attribute(self):
|
def test_function_as_instance_attribute(self):
|
||||||
obj = SomeClass()
|
obj = SomeClass()
|
||||||
def f(a):
|
def f(a): pass
|
||||||
pass
|
|
||||||
obj.f = f
|
obj.f = f
|
||||||
|
|
||||||
mock = create_autospec(obj)
|
mock = create_autospec(obj)
|
||||||
|
@ -485,13 +457,57 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
self._check_someclass_mock(mock)
|
self._check_someclass_mock(mock)
|
||||||
|
|
||||||
|
|
||||||
|
def test_spec_has_descriptor_returning_function(self):
|
||||||
|
|
||||||
|
class CrazyDescriptor(object):
|
||||||
|
|
||||||
|
def __get__(self, obj, type_):
|
||||||
|
if obj is None:
|
||||||
|
return lambda x: None
|
||||||
|
|
||||||
|
class MyClass(object):
|
||||||
|
|
||||||
|
some_attr = CrazyDescriptor()
|
||||||
|
|
||||||
|
mock = create_autospec(MyClass)
|
||||||
|
mock.some_attr(1)
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
mock.some_attr()
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
mock.some_attr(1, 2)
|
||||||
|
|
||||||
|
|
||||||
|
def test_spec_has_function_not_in_bases(self):
|
||||||
|
|
||||||
|
class CrazyClass(object):
|
||||||
|
|
||||||
|
def __dir__(self):
|
||||||
|
return super(CrazyClass, self).__dir__()+['crazy']
|
||||||
|
|
||||||
|
def __getattr__(self, item):
|
||||||
|
if item == 'crazy':
|
||||||
|
return lambda x: x
|
||||||
|
raise AttributeError(item)
|
||||||
|
|
||||||
|
inst = CrazyClass()
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
inst.other
|
||||||
|
self.assertEqual(inst.crazy(42), 42)
|
||||||
|
|
||||||
|
mock = create_autospec(inst)
|
||||||
|
mock.crazy(42)
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
mock.crazy()
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
mock.crazy(1, 2)
|
||||||
|
|
||||||
|
|
||||||
def test_builtin_functions_types(self):
|
def test_builtin_functions_types(self):
|
||||||
# we could replace builtin functions / methods with a function
|
# we could replace builtin functions / methods with a function
|
||||||
# with *args / **kwargs signature. Using the builtin method type
|
# with *args / **kwargs signature. Using the builtin method type
|
||||||
# as a spec seems to work fairly well though.
|
# as a spec seems to work fairly well though.
|
||||||
class BuiltinSubclass(list):
|
class BuiltinSubclass(list):
|
||||||
def bar(self, arg):
|
def bar(self, arg): pass
|
||||||
pass
|
|
||||||
sorted = sorted
|
sorted = sorted
|
||||||
attr = {}
|
attr = {}
|
||||||
|
|
||||||
|
@ -565,17 +581,13 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
def test_descriptors(self):
|
def test_descriptors(self):
|
||||||
class Foo(object):
|
class Foo(object):
|
||||||
@classmethod
|
@classmethod
|
||||||
def f(cls, a, b):
|
def f(cls, a, b): pass
|
||||||
pass
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def g(a, b):
|
def g(a, b): pass
|
||||||
pass
|
|
||||||
|
|
||||||
class Bar(Foo):
|
class Bar(Foo): pass
|
||||||
pass
|
|
||||||
|
|
||||||
class Baz(SomeClass, Bar):
|
class Baz(SomeClass, Bar): pass
|
||||||
pass
|
|
||||||
|
|
||||||
for spec in (Foo, Foo(), Bar, Bar(), Baz, Baz()):
|
for spec in (Foo, Foo(), Bar, Bar(), Baz, Baz()):
|
||||||
mock = create_autospec(spec)
|
mock = create_autospec(spec)
|
||||||
|
@ -588,8 +600,7 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_recursive(self):
|
def test_recursive(self):
|
||||||
class A(object):
|
class A(object):
|
||||||
def a(self):
|
def a(self): pass
|
||||||
pass
|
|
||||||
foo = 'foo bar baz'
|
foo = 'foo bar baz'
|
||||||
bar = foo
|
bar = foo
|
||||||
|
|
||||||
|
@ -611,11 +622,9 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_spec_inheritance_for_classes(self):
|
def test_spec_inheritance_for_classes(self):
|
||||||
class Foo(object):
|
class Foo(object):
|
||||||
def a(self, x):
|
def a(self, x): pass
|
||||||
pass
|
|
||||||
class Bar(object):
|
class Bar(object):
|
||||||
def f(self, y):
|
def f(self, y): pass
|
||||||
pass
|
|
||||||
|
|
||||||
class_mock = create_autospec(Foo)
|
class_mock = create_autospec(Foo)
|
||||||
|
|
||||||
|
@ -695,8 +704,7 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
def test_function(self):
|
def test_function(self):
|
||||||
def f(a, b):
|
def f(a, b): pass
|
||||||
pass
|
|
||||||
|
|
||||||
mock = create_autospec(f)
|
mock = create_autospec(f)
|
||||||
self.assertRaises(TypeError, mock)
|
self.assertRaises(TypeError, mock)
|
||||||
|
@ -726,9 +734,10 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
def existing(a, b):
|
def existing(a, b):
|
||||||
return a + b
|
return a + b
|
||||||
|
|
||||||
|
self.assertEqual(RaiserClass.existing(1, 2), 3)
|
||||||
s = create_autospec(RaiserClass)
|
s = create_autospec(RaiserClass)
|
||||||
self.assertRaises(TypeError, lambda x: s.existing(1, 2, 3))
|
self.assertRaises(TypeError, lambda x: s.existing(1, 2, 3))
|
||||||
s.existing(1, 2)
|
self.assertEqual(s.existing(1, 2), s.existing.return_value)
|
||||||
self.assertRaises(AttributeError, lambda: s.nonexisting)
|
self.assertRaises(AttributeError, lambda: s.nonexisting)
|
||||||
|
|
||||||
# check we can fetch the raiser attribute and it has no spec
|
# check we can fetch the raiser attribute and it has no spec
|
||||||
|
@ -738,8 +747,7 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_signature_class(self):
|
def test_signature_class(self):
|
||||||
class Foo(object):
|
class Foo(object):
|
||||||
def __init__(self, a, b=3):
|
def __init__(self, a, b=3): pass
|
||||||
pass
|
|
||||||
|
|
||||||
mock = create_autospec(Foo)
|
mock = create_autospec(Foo)
|
||||||
|
|
||||||
|
@ -765,10 +773,8 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_signature_callable(self):
|
def test_signature_callable(self):
|
||||||
class Callable(object):
|
class Callable(object):
|
||||||
def __init__(self, x, y):
|
def __init__(self, x, y): pass
|
||||||
pass
|
def __call__(self, a): pass
|
||||||
def __call__(self, a):
|
|
||||||
pass
|
|
||||||
|
|
||||||
mock = create_autospec(Callable)
|
mock = create_autospec(Callable)
|
||||||
mock(1, 2)
|
mock(1, 2)
|
||||||
|
@ -824,8 +830,7 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_autospec_functions_with_self_in_odd_place(self):
|
def test_autospec_functions_with_self_in_odd_place(self):
|
||||||
class Foo(object):
|
class Foo(object):
|
||||||
def f(a, self):
|
def f(a, self): pass
|
||||||
pass
|
|
||||||
|
|
||||||
a = create_autospec(Foo)
|
a = create_autospec(Foo)
|
||||||
a.f(10)
|
a.f(10)
|
||||||
|
@ -842,12 +847,9 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
def __get__(self, obj, cls=None):
|
def __get__(self, obj, cls=None):
|
||||||
if obj is None:
|
return self
|
||||||
return self
|
|
||||||
return self.value
|
|
||||||
|
|
||||||
def __set__(self, obj, value):
|
def __set__(self, obj, value): pass
|
||||||
pass
|
|
||||||
|
|
||||||
class MyProperty(property):
|
class MyProperty(property):
|
||||||
pass
|
pass
|
||||||
|
@ -856,12 +858,10 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
__slots__ = ['slot']
|
__slots__ = ['slot']
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def prop(self):
|
def prop(self): pass
|
||||||
return 3
|
|
||||||
|
|
||||||
@MyProperty
|
@MyProperty
|
||||||
def subprop(self):
|
def subprop(self): pass
|
||||||
return 4
|
|
||||||
|
|
||||||
desc = Descriptor(42)
|
desc = Descriptor(42)
|
||||||
|
|
||||||
|
@ -913,8 +913,7 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_spec_inspect_signature(self):
|
def test_spec_inspect_signature(self):
|
||||||
|
|
||||||
def myfunc(x, y):
|
def myfunc(x, y): pass
|
||||||
pass
|
|
||||||
|
|
||||||
mock = create_autospec(myfunc)
|
mock = create_autospec(myfunc)
|
||||||
mock(1, 2)
|
mock(1, 2)
|
||||||
|
@ -930,6 +929,7 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
def foo(a: int, b: int=10, *, c:int) -> int:
|
def foo(a: int, b: int=10, *, c:int) -> int:
|
||||||
return a + b + c
|
return a + b + c
|
||||||
|
|
||||||
|
self.assertEqual(foo(1, 2 , c=3), 6)
|
||||||
mock = create_autospec(foo)
|
mock = create_autospec(foo)
|
||||||
mock(1, 2, c=3)
|
mock(1, 2, c=3)
|
||||||
mock(1, c=3)
|
mock(1, c=3)
|
||||||
|
@ -940,6 +940,42 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, mock, 1, 2, 3, c=4)
|
self.assertRaises(TypeError, mock, 1, 2, 3, c=4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_spec_function_no_name(self):
|
||||||
|
func = lambda: 'nope'
|
||||||
|
mock = create_autospec(func)
|
||||||
|
self.assertEqual(mock.__name__, 'funcopy')
|
||||||
|
|
||||||
|
|
||||||
|
def test_spec_function_assert_has_calls(self):
|
||||||
|
def f(a): pass
|
||||||
|
mock = create_autospec(f)
|
||||||
|
mock(1)
|
||||||
|
mock.assert_has_calls([call(1)])
|
||||||
|
with self.assertRaises(AssertionError):
|
||||||
|
mock.assert_has_calls([call(2)])
|
||||||
|
|
||||||
|
|
||||||
|
def test_spec_function_assert_any_call(self):
|
||||||
|
def f(a): pass
|
||||||
|
mock = create_autospec(f)
|
||||||
|
mock(1)
|
||||||
|
mock.assert_any_call(1)
|
||||||
|
with self.assertRaises(AssertionError):
|
||||||
|
mock.assert_any_call(2)
|
||||||
|
|
||||||
|
|
||||||
|
def test_spec_function_reset_mock(self):
|
||||||
|
def f(a): pass
|
||||||
|
rv = Mock()
|
||||||
|
mock = create_autospec(f, return_value=rv)
|
||||||
|
mock(1)(2)
|
||||||
|
self.assertEqual(mock.mock_calls, [call(1)])
|
||||||
|
self.assertEqual(rv.mock_calls, [call(2)])
|
||||||
|
mock.reset_mock()
|
||||||
|
self.assertEqual(mock.mock_calls, [])
|
||||||
|
self.assertEqual(rv.mock_calls, [])
|
||||||
|
|
||||||
|
|
||||||
class TestCallList(unittest.TestCase):
|
class TestCallList(unittest.TestCase):
|
||||||
|
|
||||||
def test_args_list_contains_call_list(self):
|
def test_args_list_contains_call_list(self):
|
||||||
|
@ -1019,16 +1055,14 @@ class TestCallablePredicate(unittest.TestCase):
|
||||||
|
|
||||||
def test_call_magic_method(self):
|
def test_call_magic_method(self):
|
||||||
class Callable:
|
class Callable:
|
||||||
def __call__(self):
|
def __call__(self): pass
|
||||||
pass
|
|
||||||
instance = Callable()
|
instance = Callable()
|
||||||
self.assertTrue(_callable(instance))
|
self.assertTrue(_callable(instance))
|
||||||
|
|
||||||
def test_staticmethod(self):
|
def test_staticmethod(self):
|
||||||
class WithStaticMethod:
|
class WithStaticMethod:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def staticfunc():
|
def staticfunc(): pass
|
||||||
pass
|
|
||||||
self.assertTrue(_callable(WithStaticMethod.staticfunc))
|
self.assertTrue(_callable(WithStaticMethod.staticfunc))
|
||||||
|
|
||||||
def test_non_callable_staticmethod(self):
|
def test_non_callable_staticmethod(self):
|
||||||
|
@ -1039,8 +1073,7 @@ class TestCallablePredicate(unittest.TestCase):
|
||||||
def test_classmethod(self):
|
def test_classmethod(self):
|
||||||
class WithClassMethod:
|
class WithClassMethod:
|
||||||
@classmethod
|
@classmethod
|
||||||
def classfunc(cls):
|
def classfunc(cls): pass
|
||||||
pass
|
|
||||||
self.assertTrue(_callable(WithClassMethod.classfunc))
|
self.assertTrue(_callable(WithClassMethod.classfunc))
|
||||||
|
|
||||||
def test_non_callable_classmethod(self):
|
def test_non_callable_classmethod(self):
|
||||||
|
|
|
@ -305,8 +305,7 @@ class TestMockingMagicMethods(unittest.TestCase):
|
||||||
|
|
||||||
def test_magic_methods_and_spec(self):
|
def test_magic_methods_and_spec(self):
|
||||||
class Iterable(object):
|
class Iterable(object):
|
||||||
def __iter__(self):
|
def __iter__(self): pass
|
||||||
pass
|
|
||||||
|
|
||||||
mock = Mock(spec=Iterable)
|
mock = Mock(spec=Iterable)
|
||||||
self.assertRaises(AttributeError, lambda: mock.__iter__)
|
self.assertRaises(AttributeError, lambda: mock.__iter__)
|
||||||
|
@ -330,8 +329,7 @@ class TestMockingMagicMethods(unittest.TestCase):
|
||||||
|
|
||||||
def test_magic_methods_and_spec_set(self):
|
def test_magic_methods_and_spec_set(self):
|
||||||
class Iterable(object):
|
class Iterable(object):
|
||||||
def __iter__(self):
|
def __iter__(self): pass
|
||||||
pass
|
|
||||||
|
|
||||||
mock = Mock(spec_set=Iterable)
|
mock = Mock(spec_set=Iterable)
|
||||||
self.assertRaises(AttributeError, lambda: mock.__iter__)
|
self.assertRaises(AttributeError, lambda: mock.__iter__)
|
||||||
|
|
|
@ -28,16 +28,13 @@ class Iter(object):
|
||||||
|
|
||||||
|
|
||||||
class Something(object):
|
class Something(object):
|
||||||
def meth(self, a, b, c, d=None):
|
def meth(self, a, b, c, d=None): pass
|
||||||
pass
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def cmeth(cls, a, b, c, d=None):
|
def cmeth(cls, a, b, c, d=None): pass
|
||||||
pass
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def smeth(a, b, c, d=None):
|
def smeth(a, b, c, d=None): pass
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class MockTest(unittest.TestCase):
|
class MockTest(unittest.TestCase):
|
||||||
|
@ -83,6 +80,21 @@ class MockTest(unittest.TestCase):
|
||||||
"return value in constructor not honoured")
|
"return value in constructor not honoured")
|
||||||
|
|
||||||
|
|
||||||
|
def test_change_return_value_via_delegate(self):
|
||||||
|
def f(): pass
|
||||||
|
mock = create_autospec(f)
|
||||||
|
mock.mock.return_value = 1
|
||||||
|
self.assertEqual(mock(), 1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_change_side_effect_via_delegate(self):
|
||||||
|
def f(): pass
|
||||||
|
mock = create_autospec(f)
|
||||||
|
mock.mock.side_effect = TypeError()
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
mock()
|
||||||
|
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
mock = Mock(name='foo')
|
mock = Mock(name='foo')
|
||||||
self.assertIn('foo', repr(mock))
|
self.assertIn('foo', repr(mock))
|
||||||
|
@ -161,8 +173,7 @@ class MockTest(unittest.TestCase):
|
||||||
results = [1, 2, 3]
|
results = [1, 2, 3]
|
||||||
def effect():
|
def effect():
|
||||||
return results.pop()
|
return results.pop()
|
||||||
def f():
|
def f(): pass
|
||||||
pass
|
|
||||||
|
|
||||||
mock = create_autospec(f)
|
mock = create_autospec(f)
|
||||||
mock.side_effect = [1, 2, 3]
|
mock.side_effect = [1, 2, 3]
|
||||||
|
@ -177,8 +188,7 @@ class MockTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_autospec_side_effect_exception(self):
|
def test_autospec_side_effect_exception(self):
|
||||||
# Test for issue 23661
|
# Test for issue 23661
|
||||||
def f():
|
def f(): pass
|
||||||
pass
|
|
||||||
|
|
||||||
mock = create_autospec(f)
|
mock = create_autospec(f)
|
||||||
mock.side_effect = ValueError('Bazinga!')
|
mock.side_effect = ValueError('Bazinga!')
|
||||||
|
@ -340,8 +350,7 @@ class MockTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
def test_assert_called_with_function_spec(self):
|
def test_assert_called_with_function_spec(self):
|
||||||
def f(a, b, c, d=None):
|
def f(a, b, c, d=None): pass
|
||||||
pass
|
|
||||||
|
|
||||||
mock = Mock(spec=f)
|
mock = Mock(spec=f)
|
||||||
|
|
||||||
|
@ -409,8 +418,7 @@ class MockTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
def test_assert_called_once_with_function_spec(self):
|
def test_assert_called_once_with_function_spec(self):
|
||||||
def f(a, b, c, d=None):
|
def f(a, b, c, d=None): pass
|
||||||
pass
|
|
||||||
|
|
||||||
mock = Mock(spec=f)
|
mock = Mock(spec=f)
|
||||||
|
|
||||||
|
@ -514,8 +522,7 @@ class MockTest(unittest.TestCase):
|
||||||
class Something(object):
|
class Something(object):
|
||||||
x = 3
|
x = 3
|
||||||
__something__ = None
|
__something__ = None
|
||||||
def y(self):
|
def y(self): pass
|
||||||
pass
|
|
||||||
|
|
||||||
def test_attributes(mock):
|
def test_attributes(mock):
|
||||||
# should work
|
# should work
|
||||||
|
@ -601,8 +608,7 @@ class MockTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_customize_wrapped_object_with_side_effect_iterable(self):
|
def test_customize_wrapped_object_with_side_effect_iterable(self):
|
||||||
class Real(object):
|
class Real(object):
|
||||||
def method(self):
|
def method(self): pass
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
real = Real()
|
real = Real()
|
||||||
mock = Mock(wraps=real)
|
mock = Mock(wraps=real)
|
||||||
|
@ -615,8 +621,7 @@ class MockTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_customize_wrapped_object_with_side_effect_exception(self):
|
def test_customize_wrapped_object_with_side_effect_exception(self):
|
||||||
class Real(object):
|
class Real(object):
|
||||||
def method(self):
|
def method(self): pass
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
real = Real()
|
real = Real()
|
||||||
mock = Mock(wraps=real)
|
mock = Mock(wraps=real)
|
||||||
|
@ -627,9 +632,7 @@ class MockTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_customize_wrapped_object_with_side_effect_function(self):
|
def test_customize_wrapped_object_with_side_effect_function(self):
|
||||||
class Real(object):
|
class Real(object):
|
||||||
def method(self):
|
def method(self): pass
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
def side_effect():
|
def side_effect():
|
||||||
return sentinel.VALUE
|
return sentinel.VALUE
|
||||||
|
|
||||||
|
@ -642,8 +645,7 @@ class MockTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_customize_wrapped_object_with_return_value(self):
|
def test_customize_wrapped_object_with_return_value(self):
|
||||||
class Real(object):
|
class Real(object):
|
||||||
def method(self):
|
def method(self): pass
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
real = Real()
|
real = Real()
|
||||||
mock = Mock(wraps=real)
|
mock = Mock(wraps=real)
|
||||||
|
@ -655,8 +657,7 @@ class MockTest(unittest.TestCase):
|
||||||
def test_customize_wrapped_object_with_return_value_and_side_effect(self):
|
def test_customize_wrapped_object_with_return_value_and_side_effect(self):
|
||||||
# side_effect should always take precedence over return_value.
|
# side_effect should always take precedence over return_value.
|
||||||
class Real(object):
|
class Real(object):
|
||||||
def method(self):
|
def method(self): pass
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
real = Real()
|
real = Real()
|
||||||
mock = Mock(wraps=real)
|
mock = Mock(wraps=real)
|
||||||
|
@ -671,8 +672,7 @@ class MockTest(unittest.TestCase):
|
||||||
def test_customize_wrapped_object_with_return_value_and_side_effect2(self):
|
def test_customize_wrapped_object_with_return_value_and_side_effect2(self):
|
||||||
# side_effect can return DEFAULT to default to return_value
|
# side_effect can return DEFAULT to default to return_value
|
||||||
class Real(object):
|
class Real(object):
|
||||||
def method(self):
|
def method(self): pass
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
real = Real()
|
real = Real()
|
||||||
mock = Mock(wraps=real)
|
mock = Mock(wraps=real)
|
||||||
|
@ -684,8 +684,7 @@ class MockTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_customize_wrapped_object_with_return_value_and_side_effect_default(self):
|
def test_customize_wrapped_object_with_return_value_and_side_effect_default(self):
|
||||||
class Real(object):
|
class Real(object):
|
||||||
def method(self):
|
def method(self): pass
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
real = Real()
|
real = Real()
|
||||||
mock = Mock(wraps=real)
|
mock = Mock(wraps=real)
|
||||||
|
@ -764,6 +763,26 @@ class MockTest(unittest.TestCase):
|
||||||
self.assertIsInstance(mock, X)
|
self.assertIsInstance(mock, X)
|
||||||
|
|
||||||
|
|
||||||
|
def test_spec_class_no_object_base(self):
|
||||||
|
class X:
|
||||||
|
pass
|
||||||
|
|
||||||
|
mock = Mock(spec=X)
|
||||||
|
self.assertIsInstance(mock, X)
|
||||||
|
|
||||||
|
mock = Mock(spec=X())
|
||||||
|
self.assertIsInstance(mock, X)
|
||||||
|
|
||||||
|
self.assertIs(mock.__class__, X)
|
||||||
|
self.assertEqual(Mock().__class__.__name__, 'Mock')
|
||||||
|
|
||||||
|
mock = Mock(spec_set=X)
|
||||||
|
self.assertIsInstance(mock, X)
|
||||||
|
|
||||||
|
mock = Mock(spec_set=X())
|
||||||
|
self.assertIsInstance(mock, X)
|
||||||
|
|
||||||
|
|
||||||
def test_setting_attribute_with_spec_set(self):
|
def test_setting_attribute_with_spec_set(self):
|
||||||
class X(object):
|
class X(object):
|
||||||
y = 3
|
y = 3
|
||||||
|
@ -902,15 +921,9 @@ class MockTest(unittest.TestCase):
|
||||||
|
|
||||||
def assertRaisesWithMsg(self, exception, message, func, *args, **kwargs):
|
def assertRaisesWithMsg(self, exception, message, func, *args, **kwargs):
|
||||||
# needed because assertRaisesRegex doesn't work easily with newlines
|
# needed because assertRaisesRegex doesn't work easily with newlines
|
||||||
try:
|
with self.assertRaises(exception) as context:
|
||||||
func(*args, **kwargs)
|
func(*args, **kwargs)
|
||||||
except:
|
msg = str(context.exception)
|
||||||
instance = sys.exc_info()[1]
|
|
||||||
self.assertIsInstance(instance, exception)
|
|
||||||
else:
|
|
||||||
self.fail('Exception %r not raised' % (exception,))
|
|
||||||
|
|
||||||
msg = str(instance)
|
|
||||||
self.assertEqual(msg, message)
|
self.assertEqual(msg, message)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1099,6 +1112,18 @@ class MockTest(unittest.TestCase):
|
||||||
self.assertEqual(repr(m.mock_calls[2]), 'call.foo().bar().baz.bob()')
|
self.assertEqual(repr(m.mock_calls[2]), 'call.foo().bar().baz.bob()')
|
||||||
|
|
||||||
|
|
||||||
|
def test_mock_call_repr_loop(self):
|
||||||
|
m = Mock()
|
||||||
|
m.foo = m
|
||||||
|
repr(m.foo())
|
||||||
|
self.assertRegex(repr(m.foo()), r"<Mock name='mock\(\)' id='\d+'>")
|
||||||
|
|
||||||
|
|
||||||
|
def test_mock_calls_contains(self):
|
||||||
|
m = Mock()
|
||||||
|
self.assertFalse([call()] in m.mock_calls)
|
||||||
|
|
||||||
|
|
||||||
def test_subclassing(self):
|
def test_subclassing(self):
|
||||||
class Subclass(Mock):
|
class Subclass(Mock):
|
||||||
pass
|
pass
|
||||||
|
@ -1312,8 +1337,7 @@ class MockTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
def test_assert_has_calls_with_function_spec(self):
|
def test_assert_has_calls_with_function_spec(self):
|
||||||
def f(a, b, c, d=None):
|
def f(a, b, c, d=None): pass
|
||||||
pass
|
|
||||||
|
|
||||||
mock = Mock(spec=f)
|
mock = Mock(spec=f)
|
||||||
|
|
||||||
|
@ -1371,8 +1395,7 @@ class MockTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
def test_assert_any_call_with_function_spec(self):
|
def test_assert_any_call_with_function_spec(self):
|
||||||
def f(a, b, c, d=None):
|
def f(a, b, c, d=None): pass
|
||||||
pass
|
|
||||||
|
|
||||||
mock = Mock(spec=f)
|
mock = Mock(spec=f)
|
||||||
|
|
||||||
|
@ -1391,8 +1414,7 @@ class MockTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
def test_mock_calls_create_autospec(self):
|
def test_mock_calls_create_autospec(self):
|
||||||
def f(a, b):
|
def f(a, b): pass
|
||||||
pass
|
|
||||||
obj = Iter()
|
obj = Iter()
|
||||||
obj.f = f
|
obj.f = f
|
||||||
|
|
||||||
|
@ -1417,12 +1439,10 @@ class MockTest(unittest.TestCase):
|
||||||
def test_create_autospec_classmethod_and_staticmethod(self):
|
def test_create_autospec_classmethod_and_staticmethod(self):
|
||||||
class TestClass:
|
class TestClass:
|
||||||
@classmethod
|
@classmethod
|
||||||
def class_method(cls):
|
def class_method(cls): pass
|
||||||
pass
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def static_method():
|
def static_method(): pass
|
||||||
pass
|
|
||||||
for method in ('class_method', 'static_method'):
|
for method in ('class_method', 'static_method'):
|
||||||
with self.subTest(method=method):
|
with self.subTest(method=method):
|
||||||
mock_method = mock.create_autospec(getattr(TestClass, method))
|
mock_method = mock.create_autospec(getattr(TestClass, method))
|
||||||
|
@ -1848,8 +1868,7 @@ class MockTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_parent_propagation_with_create_autospec(self):
|
def test_parent_propagation_with_create_autospec(self):
|
||||||
|
|
||||||
def foo(a, b):
|
def foo(a, b): pass
|
||||||
pass
|
|
||||||
|
|
||||||
mock = Mock()
|
mock = Mock()
|
||||||
mock.child = create_autospec(foo)
|
mock.child = create_autospec(foo)
|
||||||
|
@ -1878,11 +1897,12 @@ class MockTest(unittest.TestCase):
|
||||||
with patch.dict('sys.modules'):
|
with patch.dict('sys.modules'):
|
||||||
del sys.modules['unittest.mock']
|
del sys.modules['unittest.mock']
|
||||||
|
|
||||||
def trace(frame, event, arg):
|
# This trace will stop coverage being measured ;-)
|
||||||
|
def trace(frame, event, arg): # pragma: no cover
|
||||||
return trace
|
return trace
|
||||||
|
|
||||||
|
self.addCleanup(sys.settrace, sys.gettrace())
|
||||||
sys.settrace(trace)
|
sys.settrace(trace)
|
||||||
self.addCleanup(sys.settrace, None)
|
|
||||||
|
|
||||||
from unittest.mock import (
|
from unittest.mock import (
|
||||||
Mock, MagicMock, NonCallableMock, NonCallableMagicMock
|
Mock, MagicMock, NonCallableMock, NonCallableMagicMock
|
||||||
|
|
|
@ -43,31 +43,24 @@ something_else = sentinel.SomethingElse
|
||||||
|
|
||||||
|
|
||||||
class Foo(object):
|
class Foo(object):
|
||||||
def __init__(self, a):
|
def __init__(self, a): pass
|
||||||
pass
|
def f(self, a): pass
|
||||||
def f(self, a):
|
def g(self): pass
|
||||||
pass
|
|
||||||
def g(self):
|
|
||||||
pass
|
|
||||||
foo = 'bar'
|
foo = 'bar'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def static_method():
|
def static_method(): pass
|
||||||
return 24
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def class_method(cls):
|
def class_method(cls): pass
|
||||||
return 42
|
|
||||||
|
|
||||||
class Bar(object):
|
class Bar(object):
|
||||||
def a(self):
|
def a(self): pass
|
||||||
pass
|
|
||||||
|
|
||||||
foo_name = '%s.Foo' % __name__
|
foo_name = '%s.Foo' % __name__
|
||||||
|
|
||||||
|
|
||||||
def function(a, b=Foo):
|
def function(a, b=Foo): pass
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Container(object):
|
class Container(object):
|
||||||
|
@ -370,31 +363,19 @@ class PatchTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
def test_patch_wont_create_by_default(self):
|
def test_patch_wont_create_by_default(self):
|
||||||
try:
|
with self.assertRaises(AttributeError):
|
||||||
@patch('%s.frooble' % builtin_string, sentinel.Frooble)
|
@patch('%s.frooble' % builtin_string, sentinel.Frooble)
|
||||||
def test():
|
def test(): pass
|
||||||
self.assertEqual(frooble, sentinel.Frooble)
|
|
||||||
|
|
||||||
test()
|
test()
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.fail('Patching non existent attributes should fail')
|
|
||||||
|
|
||||||
self.assertRaises(NameError, lambda: frooble)
|
self.assertRaises(NameError, lambda: frooble)
|
||||||
|
|
||||||
|
|
||||||
def test_patchobject_wont_create_by_default(self):
|
def test_patchobject_wont_create_by_default(self):
|
||||||
try:
|
with self.assertRaises(AttributeError):
|
||||||
@patch.object(SomeClass, 'ord', sentinel.Frooble)
|
@patch.object(SomeClass, 'ord', sentinel.Frooble)
|
||||||
def test():
|
def test(): pass
|
||||||
self.fail('Patching non existent attributes should fail')
|
|
||||||
|
|
||||||
test()
|
test()
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.fail('Patching non existent attributes should fail')
|
|
||||||
self.assertFalse(hasattr(SomeClass, 'ord'))
|
self.assertFalse(hasattr(SomeClass, 'ord'))
|
||||||
|
|
||||||
|
|
||||||
|
@ -484,6 +465,9 @@ class PatchTest(unittest.TestCase):
|
||||||
attribute = sentinel.Original
|
attribute = sentinel.Original
|
||||||
|
|
||||||
class Foo(object):
|
class Foo(object):
|
||||||
|
|
||||||
|
test_class_attr = 'whatever'
|
||||||
|
|
||||||
def test_method(other_self, mock_something):
|
def test_method(other_self, mock_something):
|
||||||
self.assertEqual(PTModule.something, mock_something,
|
self.assertEqual(PTModule.something, mock_something,
|
||||||
"unpatched")
|
"unpatched")
|
||||||
|
@ -642,8 +626,7 @@ class PatchTest(unittest.TestCase):
|
||||||
@patch('%s.SomeClass' % __name__, object(), autospec=True)
|
@patch('%s.SomeClass' % __name__, object(), autospec=True)
|
||||||
@patch.object(SomeClass, object())
|
@patch.object(SomeClass, object())
|
||||||
@patch.dict(foo)
|
@patch.dict(foo)
|
||||||
def some_name():
|
def some_name(): pass
|
||||||
pass
|
|
||||||
|
|
||||||
self.assertEqual(some_name.__name__, 'some_name')
|
self.assertEqual(some_name.__name__, 'some_name')
|
||||||
|
|
||||||
|
@ -654,12 +637,9 @@ class PatchTest(unittest.TestCase):
|
||||||
@patch.dict(foo, {'a': 'b'})
|
@patch.dict(foo, {'a': 'b'})
|
||||||
def test():
|
def test():
|
||||||
raise NameError('Konrad')
|
raise NameError('Konrad')
|
||||||
try:
|
|
||||||
|
with self.assertRaises(NameError):
|
||||||
test()
|
test()
|
||||||
except NameError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.fail('NameError not raised by test')
|
|
||||||
|
|
||||||
self.assertEqual(foo, {})
|
self.assertEqual(foo, {})
|
||||||
|
|
||||||
|
@ -689,49 +669,6 @@ class PatchTest(unittest.TestCase):
|
||||||
support.target = original
|
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):
|
def test_patch_spec_set(self):
|
||||||
@patch('%s.SomeClass' % __name__, spec=SomeClass, spec_set=True)
|
@patch('%s.SomeClass' % __name__, spec=SomeClass, spec_set=True)
|
||||||
def test(MockClass):
|
def test(MockClass):
|
||||||
|
@ -931,17 +868,13 @@ class PatchTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_autospec(self):
|
def test_autospec(self):
|
||||||
class Boo(object):
|
class Boo(object):
|
||||||
def __init__(self, a):
|
def __init__(self, a): pass
|
||||||
pass
|
def f(self, a): pass
|
||||||
def f(self, a):
|
def g(self): pass
|
||||||
pass
|
|
||||||
def g(self):
|
|
||||||
pass
|
|
||||||
foo = 'bar'
|
foo = 'bar'
|
||||||
|
|
||||||
class Bar(object):
|
class Bar(object):
|
||||||
def a(self):
|
def a(self): pass
|
||||||
pass
|
|
||||||
|
|
||||||
def _test(mock):
|
def _test(mock):
|
||||||
mock(1)
|
mock(1)
|
||||||
|
@ -1488,20 +1421,17 @@ class PatchTest(unittest.TestCase):
|
||||||
@patch.object(Foo, 'g', 1)
|
@patch.object(Foo, 'g', 1)
|
||||||
@patch.object(Foo, 'missing', 1)
|
@patch.object(Foo, 'missing', 1)
|
||||||
@patch.object(Foo, 'f', 1)
|
@patch.object(Foo, 'f', 1)
|
||||||
def thing1():
|
def thing1(): pass
|
||||||
pass
|
|
||||||
|
|
||||||
@patch.object(Foo, 'missing', 1)
|
@patch.object(Foo, 'missing', 1)
|
||||||
@patch.object(Foo, 'g', 1)
|
@patch.object(Foo, 'g', 1)
|
||||||
@patch.object(Foo, 'f', 1)
|
@patch.object(Foo, 'f', 1)
|
||||||
def thing2():
|
def thing2(): pass
|
||||||
pass
|
|
||||||
|
|
||||||
@patch.object(Foo, 'g', 1)
|
@patch.object(Foo, 'g', 1)
|
||||||
@patch.object(Foo, 'f', 1)
|
@patch.object(Foo, 'f', 1)
|
||||||
@patch.object(Foo, 'missing', 1)
|
@patch.object(Foo, 'missing', 1)
|
||||||
def thing3():
|
def thing3(): pass
|
||||||
pass
|
|
||||||
|
|
||||||
for func in thing1, thing2, thing3:
|
for func in thing1, thing2, thing3:
|
||||||
self.assertRaises(AttributeError, func)
|
self.assertRaises(AttributeError, func)
|
||||||
|
@ -1520,20 +1450,17 @@ class PatchTest(unittest.TestCase):
|
||||||
@patch.object(Foo, 'g', 1)
|
@patch.object(Foo, 'g', 1)
|
||||||
@patch.object(Foo, 'foo', new_callable=crasher)
|
@patch.object(Foo, 'foo', new_callable=crasher)
|
||||||
@patch.object(Foo, 'f', 1)
|
@patch.object(Foo, 'f', 1)
|
||||||
def thing1():
|
def thing1(): pass
|
||||||
pass
|
|
||||||
|
|
||||||
@patch.object(Foo, 'foo', new_callable=crasher)
|
@patch.object(Foo, 'foo', new_callable=crasher)
|
||||||
@patch.object(Foo, 'g', 1)
|
@patch.object(Foo, 'g', 1)
|
||||||
@patch.object(Foo, 'f', 1)
|
@patch.object(Foo, 'f', 1)
|
||||||
def thing2():
|
def thing2(): pass
|
||||||
pass
|
|
||||||
|
|
||||||
@patch.object(Foo, 'g', 1)
|
@patch.object(Foo, 'g', 1)
|
||||||
@patch.object(Foo, 'f', 1)
|
@patch.object(Foo, 'f', 1)
|
||||||
@patch.object(Foo, 'foo', new_callable=crasher)
|
@patch.object(Foo, 'foo', new_callable=crasher)
|
||||||
def thing3():
|
def thing3(): pass
|
||||||
pass
|
|
||||||
|
|
||||||
for func in thing1, thing2, thing3:
|
for func in thing1, thing2, thing3:
|
||||||
self.assertRaises(NameError, func)
|
self.assertRaises(NameError, func)
|
||||||
|
@ -1559,8 +1486,7 @@ class PatchTest(unittest.TestCase):
|
||||||
patcher.additional_patchers = additionals
|
patcher.additional_patchers = additionals
|
||||||
|
|
||||||
@patcher
|
@patcher
|
||||||
def func():
|
def func(): pass
|
||||||
pass
|
|
||||||
|
|
||||||
self.assertRaises(AttributeError, func)
|
self.assertRaises(AttributeError, func)
|
||||||
self.assertEqual(Foo.f, original_f)
|
self.assertEqual(Foo.f, original_f)
|
||||||
|
@ -1588,8 +1514,7 @@ class PatchTest(unittest.TestCase):
|
||||||
patcher.additional_patchers = additionals
|
patcher.additional_patchers = additionals
|
||||||
|
|
||||||
@patcher
|
@patcher
|
||||||
def func():
|
def func(): pass
|
||||||
pass
|
|
||||||
|
|
||||||
self.assertRaises(NameError, func)
|
self.assertRaises(NameError, func)
|
||||||
self.assertEqual(Foo.f, original_f)
|
self.assertEqual(Foo.f, original_f)
|
||||||
|
@ -1898,5 +1823,36 @@ class PatchTest(unittest.TestCase):
|
||||||
self.assertEqual(foo(), 1)
|
self.assertEqual(foo(), 1)
|
||||||
self.assertEqual(foo(), 0)
|
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__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -3,15 +3,10 @@ from unittest import mock
|
||||||
|
|
||||||
|
|
||||||
class SampleObject:
|
class SampleObject:
|
||||||
def __init__(self):
|
|
||||||
self.attr_sample1 = 1
|
|
||||||
self.attr_sample2 = 1
|
|
||||||
|
|
||||||
def method_sample1(self):
|
def method_sample1(self): pass
|
||||||
pass
|
|
||||||
|
|
||||||
def method_sample2(self):
|
def method_sample2(self): pass
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TestSealable(unittest.TestCase):
|
class TestSealable(unittest.TestCase):
|
||||||
|
|
|
@ -10,6 +10,8 @@ something = sentinel.Something
|
||||||
something_else = sentinel.SomethingElse
|
something_else = sentinel.SomethingElse
|
||||||
|
|
||||||
|
|
||||||
|
class SampleException(Exception): pass
|
||||||
|
|
||||||
|
|
||||||
class WithTest(unittest.TestCase):
|
class WithTest(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -20,14 +22,10 @@ class WithTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
def test_with_statement_exception(self):
|
def test_with_statement_exception(self):
|
||||||
try:
|
with self.assertRaises(SampleException):
|
||||||
with patch('%s.something' % __name__, sentinel.Something2):
|
with patch('%s.something' % __name__, sentinel.Something2):
|
||||||
self.assertEqual(something, sentinel.Something2, "unpatched")
|
self.assertEqual(something, sentinel.Something2, "unpatched")
|
||||||
raise Exception('pow')
|
raise SampleException()
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.fail("patch swallowed exception")
|
|
||||||
self.assertEqual(something, sentinel.Something)
|
self.assertEqual(something, sentinel.Something)
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,8 +126,7 @@ class WithTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_double_patch_instance_method(self):
|
def test_double_patch_instance_method(self):
|
||||||
class C:
|
class C:
|
||||||
def f(self):
|
def f(self): pass
|
||||||
pass
|
|
||||||
|
|
||||||
c = C()
|
c = C()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue