diff options
author | Chris Withers <chris@withers.org> | 2019-05-01 22:04:04 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-01 22:04:04 (GMT) |
commit | adbf178e49113b2de0042e86a1228560475a65c5 (patch) | |
tree | 871ac21aec993e310f915cf2781909282a7a03e9 /Lib/unittest/mock.py | |
parent | b7378d77289c911ca6a0c0afaf513879002df7d5 (diff) | |
download | cpython-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.py | 61 |
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, |