summaryrefslogtreecommitdiffstats
path: root/Lib/unittest/mock.py
diff options
context:
space:
mode:
authorChris Withers <chris@withers.org>2019-05-01 22:04:04 (GMT)
committerGitHub <noreply@github.com>2019-05-01 22:04:04 (GMT)
commitadbf178e49113b2de0042e86a1228560475a65c5 (patch)
tree871ac21aec993e310f915cf2781909282a7a03e9 /Lib/unittest/mock.py
parentb7378d77289c911ca6a0c0afaf513879002df7d5 (diff)
downloadcpython-adbf178e49113b2de0042e86a1228560475a65c5.zip
cpython-adbf178e49113b2de0042e86a1228560475a65c5.tar.gz
cpython-adbf178e49113b2de0042e86a1228560475a65c5.tar.bz2
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/mock.py')
-rw-r--r--Lib/unittest/mock.py61
1 files changed, 5 insertions, 56 deletions
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 721e91f..351aba5 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -63,10 +63,7 @@ def _get_signature_object(func, as_instance, eat_self):
"""
if isinstance(func, type) and not as_instance:
# If it's a type and should be modelled as a type, use __init__.
- try:
- func = func.__init__
- except AttributeError:
- return None
+ func = func.__init__
# Skip the `self` argument in __init__
eat_self = True
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
# mock. It still does signature checking by calling a lambda with the same
# signature as the original.
- if not _callable(original):
- return
skipfirst = isinstance(original, type)
result = _get_signature_object(original, instance, skipfirst)
@@ -175,10 +170,6 @@ def _set_signature(mock, original, instance=False):
def _setup_func(funcopy, mock, sig):
funcopy.mock = mock
- # can't use isinstance with mocks
- if not _is_instance_mock(mock):
- return
-
def assert_called_with(*args, **kwargs):
return mock.assert_called_with(*args, **kwargs)
def assert_called(*args, **kwargs):
@@ -263,12 +254,6 @@ _missing = sentinel.MISSING
_deleted = sentinel.DELETED
-def _copy(value):
- if type(value) in (dict, list, tuple, set):
- return type(value)(value)
- return value
-
-
_allowed_names = {
'return_value', '_mock_return_value', 'side_effect',
'_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):
def __init__(self, obj):
self.obj = iter(obj)
- def __iter__(self):
- return self
def __next__(self):
return next(self.obj)
@@ -452,7 +435,7 @@ class NonCallableMock(Base):
if isinstance(spec, type):
_spec_class = spec
else:
- _spec_class = _get_class(spec)
+ _spec_class = type(spec)
res = _get_signature_object(spec,
_spec_as_instance, _eat_self)
_spec_signature = res and res[1]
@@ -624,7 +607,7 @@ class NonCallableMock(Base):
dot = '.'
if _name_list == ['()']:
dot = ''
- seen = set()
+
while _parent is not None:
last = _parent
@@ -635,11 +618,6 @@ class NonCallableMock(Base):
_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))
_first = last._mock_name or 'mock'
if len(_name_list) > 1:
@@ -753,8 +731,6 @@ class NonCallableMock(Base):
message = 'expected call not found.\nExpected: %s\nActual: %s'
expected_string = self._format_mock_call_signature(args, kwargs)
call_args = self.call_args
- if len(call_args) == 3:
- call_args = call_args[1:]
actual_string = self._format_mock_call_signature(*call_args)
return message % (expected_string, actual_string)
@@ -992,8 +968,6 @@ class CallableMixin(Base):
self.call_args = _call
self.call_args_list.append(_call)
- seen = set()
-
# initial stuff for method_calls:
do_method_calls = self._mock_parent is not None
method_call_name = self._mock_name
@@ -1029,13 +1003,6 @@ class CallableMixin(Base):
# follow the parental chain:
_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
if effect is not None:
if _is_exception(effect):
@@ -1858,12 +1825,7 @@ def _set_return_value(mock, method, name):
return_calulator = _calculate_return_value.get(name)
if return_calulator is not None:
- try:
- 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)
+ return_value = return_calulator(mock)
method.return_value = return_value
return
@@ -1943,10 +1905,6 @@ class MagicProxy(object):
self.name = name
self.parent = parent
- def __call__(self, *args, **kwargs):
- m = self.create_mock()
- return m(*args, **kwargs)
-
def create_mock(self):
entry = self.name
parent = self.parent
@@ -2330,19 +2288,10 @@ def _must_skip(spec, entry, is_type):
else:
return False
- # shouldn't get here unless function is a dynamically provided attribute
- # XXXX untested behaviour
+ # function is a dynamically provided attribute
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):
def __init__(self, spec, spec_set=False, parent=None,