summaryrefslogtreecommitdiff
path: root/mock
diff options
context:
space:
mode:
authorChris Withers <chris@withers.org>2019-05-01 23:04:04 +0100
committerChris Withers <chris@simplistix.co.uk>2019-05-01 23:38:12 +0100
commitf0eb0293249f17687bc80a174f331bc077f78bf4 (patch)
tree926afb0c2738d64fdab96de5bece0e5be7a3914c /mock
parented3bc8b58dfcf9734fd6308c3d82480fa9e8a132 (diff)
downloadmock-f0eb0293249f17687bc80a174f331bc077f78bf4.tar.gz
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. Backports: adbf178e49113b2de0042e86a1228560475a65c5 Signed-off-by: Chris Withers <chris@simplistix.co.uk> Some alterations had to be made for Py2 compatibility.
Diffstat (limited to 'mock')
-rw-r--r--mock/mock.py56
-rw-r--r--mock/tests/support.py3
-rw-r--r--mock/tests/testcallable.py3
-rw-r--r--mock/tests/testhelpers.py186
-rw-r--r--mock/tests/testhelpers_py3.py1
-rw-r--r--mock/tests/testmagicmethods.py6
-rw-r--r--mock/tests/testmock.py130
-rw-r--r--mock/tests/testpatch.py163
-rw-r--r--mock/tests/testsealable.py9
-rw-r--r--mock/tests/testwith.py13
10 files changed, 259 insertions, 311 deletions
diff --git a/mock/mock.py b/mock/mock.py
index a74dcde..c6a770f 100644
--- a/mock/mock.py
+++ b/mock/mock.py
@@ -259,8 +259,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, ClassTypes)
result = _get_signature_object(original, instance, skipfirst)
@@ -287,10 +285,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(*args, **kwargs):
return mock.assert_called(*args, **kwargs)
def assert_not_called(*args, **kwargs):
@@ -384,12 +378,6 @@ class OldStyleClass:
ClassType = type(OldStyleClass)
-def _copy(value):
- if type(value) in (dict, list, tuple, set):
- return type(value)(value)
- return value
-
-
ClassTypes = (type,)
if six.PY2:
ClassTypes = (type, ClassType)
@@ -476,8 +464,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)
@@ -577,7 +563,7 @@ class NonCallableMock(Base):
if isinstance(spec, ClassTypes):
_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]
@@ -749,7 +735,7 @@ class NonCallableMock(Base):
dot = '.'
if _name_list == ['()']:
dot = ''
- seen = set()
+
while _parent is not None:
last = _parent
@@ -760,11 +746,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:
@@ -882,8 +863,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)
@@ -1125,8 +1104,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
@@ -1162,13 +1139,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):
@@ -2007,12 +1977,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
@@ -2092,10 +2057,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
@@ -2499,19 +2460,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,
diff --git a/mock/tests/support.py b/mock/tests/support.py
index 933be92..d57a372 100644
--- a/mock/tests/support.py
+++ b/mock/tests/support.py
@@ -13,8 +13,7 @@ def is_instance(obj, klass):
class SomeClass(object):
class_attribute = None
- def wibble(self):
- pass
+ def wibble(self): pass
class X(object):
diff --git a/mock/tests/testcallable.py b/mock/tests/testcallable.py
index 03c8929..30e1f26 100644
--- a/mock/tests/testcallable.py
+++ b/mock/tests/testcallable.py
@@ -98,8 +98,7 @@ class TestCallable(unittest.TestCase):
def test_patch_spec_callable_class(self):
class CallableX(X):
- def __call__(self):
- pass
+ def __call__(self): pass
class Sub(CallableX):
pass
diff --git a/mock/tests/testhelpers.py b/mock/tests/testhelpers.py
index df5c577..3b86cec 100644
--- a/mock/tests/testhelpers.py
+++ b/mock/tests/testhelpers.py
@@ -24,12 +24,9 @@ if six.PY2:
class SomeClass(object):
- def one(self, a, b):
- pass
- def two(self):
- pass
- def three(self, a=None):
- pass
+ def one(self, a, b): pass
+ def two(self): pass
+ def three(self, a=None): pass
@@ -60,12 +57,9 @@ class AnyTest(unittest.TestCase):
def test_any_mock_calls_comparison_order(self):
mock = Mock()
- d = datetime.now()
class Foo(object):
- def __eq__(self, other):
- return False
- def __ne__(self, other):
- return True
+ def __eq__(self, other): pass
+ def __ne__(self, other): pass
for d in datetime.now(), Foo():
mock.reset_mock()
@@ -390,8 +384,7 @@ class SpecSignatureTest(unittest.TestCase):
def test_create_autospec_return_value(self):
- def f():
- pass
+ def f(): pass
mock = create_autospec(f, return_value='foo')
self.assertEqual(mock(), 'foo')
@@ -411,8 +404,7 @@ class SpecSignatureTest(unittest.TestCase):
def test_mocking_unbound_methods(self):
class Foo(object):
- def foo(self, foo):
- pass
+ def foo(self, foo): pass
p = patch.object(Foo, 'foo')
mock_foo = p.start()
Foo().foo(1)
@@ -420,23 +412,6 @@ class SpecSignatureTest(unittest.TestCase):
mock_foo.assert_called_with(1)
- @unittest.expectedFailure
- def test_create_autospec_unbound_methods(self):
- # see mock issue 128
- 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):
class Foo(object):
a = 3
@@ -445,7 +420,7 @@ class SpecSignatureTest(unittest.TestCase):
@unittest.skipUnless(six.PY3, "Keyword only arguments Python 3 specific")
def test_create_autospec_keyword_only_arguments(self):
- func_def = "def foo(a, *, b=None):\n pass\n"
+ func_def = "def foo(a, *, b=None): pass\n"
namespace = {}
exec (func_def, namespace)
foo = namespace['foo']
@@ -460,8 +435,7 @@ class SpecSignatureTest(unittest.TestCase):
def test_function_as_instance_attribute(self):
obj = SomeClass()
- def f(a):
- pass
+ def f(a): pass
obj.f = f
mock = create_autospec(obj)
@@ -497,6 +471,45 @@ class SpecSignatureTest(unittest.TestCase):
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)
+
+ @unittest.skipIf(six.PY2, "object.__dir__ doesn't exist in Python 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)
+
+
@unittest.skipIf('PyPy' in sys.version and sys.version_info < (3, 0),
"Fails on pypy2 due to incorrect signature for dict.pop from funcsigs")
def test_builtin_functions_types(self):
@@ -504,8 +517,7 @@ class SpecSignatureTest(unittest.TestCase):
# with *args / **kwargs signature. Using the builtin method type
# as a spec seems to work fairly well though.
class BuiltinSubclass(list):
- def bar(self, arg):
- pass
+ def bar(self, arg): pass
sorted = sorted
attr = {}
@@ -579,17 +591,13 @@ class SpecSignatureTest(unittest.TestCase):
def test_descriptors(self):
class Foo(object):
@classmethod
- def f(cls, a, b):
- pass
+ def f(cls, a, b): pass
@staticmethod
- def g(a, b):
- pass
+ def g(a, b): pass
- class Bar(Foo):
- pass
+ class Bar(Foo): pass
- class Baz(SomeClass, Bar):
- pass
+ class Baz(SomeClass, Bar): pass
for spec in (Foo, Foo(), Bar, Bar(), Baz, Baz()):
mock = create_autospec(spec)
@@ -624,8 +632,7 @@ class SpecSignatureTest(unittest.TestCase):
def test_recursive(self):
class A(object):
- def a(self):
- pass
+ def a(self): pass
foo = 'foo bar baz'
bar = foo
@@ -647,11 +654,9 @@ class SpecSignatureTest(unittest.TestCase):
def test_spec_inheritance_for_classes(self):
class Foo(object):
- def a(self, x):
- pass
+ def a(self, x): pass
class Bar(object):
- def f(self, y):
- pass
+ def f(self, y): pass
class_mock = create_autospec(Foo)
@@ -731,8 +736,7 @@ class SpecSignatureTest(unittest.TestCase):
def test_function(self):
- def f(a, b):
- pass
+ def f(a, b): pass
mock = create_autospec(f)
self.assertRaises(TypeError, mock)
@@ -762,9 +766,10 @@ class SpecSignatureTest(unittest.TestCase):
def existing(a, b):
return a + b
+ self.assertEqual(RaiserClass.existing(1, 2), 3)
s = create_autospec(RaiserClass)
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)
# check we can fetch the raiser attribute and it has no spec
@@ -774,8 +779,7 @@ class SpecSignatureTest(unittest.TestCase):
def test_signature_class(self):
class Foo(object):
- def __init__(self, a, b=3):
- pass
+ def __init__(self, a, b=3): pass
mock = create_autospec(Foo)
@@ -826,10 +830,8 @@ class SpecSignatureTest(unittest.TestCase):
def test_signature_callable(self):
class Callable(object):
- def __init__(self, x, y):
- pass
- def __call__(self, a):
- pass
+ def __init__(self, x, y): pass
+ def __call__(self, a): pass
mock = create_autospec(Callable)
mock(1, 2)
@@ -885,8 +887,7 @@ class SpecSignatureTest(unittest.TestCase):
def test_autospec_functions_with_self_in_odd_place(self):
class Foo(object):
- def f(a, self):
- pass
+ def f(a, self): pass
a = create_autospec(Foo)
a.f(10)
@@ -934,12 +935,9 @@ class SpecSignatureTest(unittest.TestCase):
self.value = value
def __get__(self, obj, cls=None):
- if obj is None:
- return self
- return self.value
+ return self
- def __set__(self, obj, value):
- pass
+ def __set__(self, obj, value): pass
class MyProperty(property):
pass
@@ -948,12 +946,10 @@ class SpecSignatureTest(unittest.TestCase):
__slots__ = ['slot']
@property
- def prop(self):
- return 3
+ def prop(self): pass
@MyProperty
- def subprop(self):
- return 4
+ def subprop(self): pass
desc = Descriptor(42)
@@ -1009,8 +1005,7 @@ class SpecSignatureTest(unittest.TestCase):
def test_spec_inspect_signature(self):
- def myfunc(x, y):
- pass
+ def myfunc(x, y): pass
mock = create_autospec(myfunc)
mock(1, 2)
@@ -1024,6 +1019,42 @@ class SpecSignatureTest(unittest.TestCase):
self.assertRaises(TypeError, mock, 1)
+ 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):
def test_args_list_contains_call_list(self):
@@ -1117,16 +1148,14 @@ class TestCallablePredicate(unittest.TestCase):
def test_call_magic_method(self):
class Callable:
- def __call__(self):
- pass
+ def __call__(self): pass
instance = Callable()
self.assertTrue(_callable(instance))
def test_staticmethod(self):
class WithStaticMethod:
@staticmethod
- def staticfunc():
- pass
+ def staticfunc(): pass
self.assertTrue(_callable(WithStaticMethod.staticfunc))
def test_non_callable_staticmethod(self):
@@ -1137,8 +1166,7 @@ class TestCallablePredicate(unittest.TestCase):
def test_classmethod(self):
class WithClassMethod:
@classmethod
- def classfunc(cls):
- pass
+ def classfunc(cls): pass
self.assertTrue(_callable(WithClassMethod.classfunc))
def test_non_callable_classmethod(self):
diff --git a/mock/tests/testhelpers_py3.py b/mock/tests/testhelpers_py3.py
index 2af91b5..64d62f8 100644
--- a/mock/tests/testhelpers_py3.py
+++ b/mock/tests/testhelpers_py3.py
@@ -12,6 +12,7 @@ class CallTest(unittest.TestCase):
def foo(a: int, b: int=10, *, c:int) -> int:
return a + b + c
+ self.assertEqual(foo(1, 2, c=3), 6)
mock = create_autospec(foo)
mock(1, 2, c=3)
mock(1, c=3)
diff --git a/mock/tests/testmagicmethods.py b/mock/tests/testmagicmethods.py
index d3d2d7c..f6c25fb 100644
--- a/mock/tests/testmagicmethods.py
+++ b/mock/tests/testmagicmethods.py
@@ -375,8 +375,7 @@ class TestMockingMagicMethods(unittest.TestCase):
def test_magic_methods_and_spec(self):
class Iterable(object):
- def __iter__(self):
- pass
+ def __iter__(self): pass
mock = Mock(spec=Iterable)
self.assertRaises(AttributeError, lambda: mock.__iter__)
@@ -400,8 +399,7 @@ class TestMockingMagicMethods(unittest.TestCase):
def test_magic_methods_and_spec_set(self):
class Iterable(object):
- def __iter__(self):
- pass
+ def __iter__(self): pass
mock = Mock(spec_set=Iterable)
self.assertRaises(AttributeError, lambda: mock.__iter__)
diff --git a/mock/tests/testmock.py b/mock/tests/testmock.py
index 7d545db..cb1cc66 100644
--- a/mock/tests/testmock.py
+++ b/mock/tests/testmock.py
@@ -41,16 +41,13 @@ class Iter(object):
class Something(object):
- def meth(self, a, b, c, d=None):
- pass
+ def meth(self, a, b, c, d=None): pass
@classmethod
- def cmeth(cls, a, b, c, d=None):
- pass
+ def cmeth(cls, a, b, c, d=None): pass
@staticmethod
- def smeth(a, b, c, d=None):
- pass
+ def smeth(a, b, c, d=None): pass
class Subclass(MagicMock):
@@ -106,6 +103,21 @@ class MockTest(unittest.TestCase):
"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):
mock = Mock(name='foo')
self.assertIn('foo', repr(mock))
@@ -184,8 +196,7 @@ class MockTest(unittest.TestCase):
results = [1, 2, 3]
def effect():
return results.pop()
- def f():
- pass
+ def f(): pass
mock = create_autospec(f)
mock.side_effect = [1, 2, 3]
@@ -200,8 +211,7 @@ class MockTest(unittest.TestCase):
def test_autospec_side_effect_exception(self):
# Test for issue 23661
- def f():
- pass
+ def f(): pass
mock = create_autospec(f)
mock.side_effect = ValueError('Bazinga!')
@@ -362,8 +372,7 @@ class MockTest(unittest.TestCase):
def test_assert_called_with_function_spec(self):
- def f(a, b, c, d=None):
- pass
+ def f(a, b, c, d=None): pass
mock = Mock(spec=f)
@@ -432,8 +441,7 @@ class MockTest(unittest.TestCase):
def test_assert_called_once_with_function_spec(self):
- def f(a, b, c, d=None):
- pass
+ def f(a, b, c, d=None): pass
mock = Mock(spec=f)
@@ -538,8 +546,7 @@ class MockTest(unittest.TestCase):
class Something(object):
x = 3
__something__ = None
- def y(self):
- pass
+ def y(self): pass
def test_attributes(mock):
# should work
@@ -625,8 +632,7 @@ class MockTest(unittest.TestCase):
def test_customize_wrapped_object_with_side_effect_iterable(self):
class Real(object):
- def method(self):
- raise NotImplementedError()
+ def method(self): pass
real = Real()
mock = Mock(wraps=real)
@@ -639,8 +645,7 @@ class MockTest(unittest.TestCase):
def test_customize_wrapped_object_with_side_effect_exception(self):
class Real(object):
- def method(self):
- raise NotImplementedError()
+ def method(self): pass
real = Real()
mock = Mock(wraps=real)
@@ -651,9 +656,7 @@ class MockTest(unittest.TestCase):
def test_customize_wrapped_object_with_side_effect_function(self):
class Real(object):
- def method(self):
- raise NotImplementedError()
-
+ def method(self): pass
def side_effect():
return sentinel.VALUE
@@ -666,8 +669,7 @@ class MockTest(unittest.TestCase):
def test_customize_wrapped_object_with_return_value(self):
class Real(object):
- def method(self):
- raise NotImplementedError()
+ def method(self): pass
real = Real()
mock = Mock(wraps=real)
@@ -679,8 +681,7 @@ class MockTest(unittest.TestCase):
def test_customize_wrapped_object_with_return_value_and_side_effect(self):
# side_effect should always take precedence over return_value.
class Real(object):
- def method(self):
- raise NotImplementedError()
+ def method(self): pass
real = Real()
mock = Mock(wraps=real)
@@ -695,8 +696,7 @@ class MockTest(unittest.TestCase):
def test_customize_wrapped_object_with_return_value_and_side_effect2(self):
# side_effect can return DEFAULT to default to return_value
class Real(object):
- def method(self):
- raise NotImplementedError()
+ def method(self): pass
real = Real()
mock = Mock(wraps=real)
@@ -708,8 +708,7 @@ class MockTest(unittest.TestCase):
def test_customize_wrapped_object_with_return_value_and_side_effect_default(self):
class Real(object):
- def method(self):
- raise NotImplementedError()
+ def method(self): pass
real = Real()
mock = Mock(wraps=real)
@@ -788,6 +787,30 @@ class MockTest(unittest.TestCase):
self.assertIsInstance(mock, X)
+ def test_spec_class_no_object_base(self):
+ class X:
+ pass
+
+ mock = Mock(spec=X)
+ self.assertIsInstance(mock, X)
+
+ if not six.PY2:
+ # This isn't true on Py2, we should fix if anyone complains:
+ 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)
+
+ if not six.PY2:
+ # This isn't true on Py2, we should fix if anyone complains:
+ mock = Mock(spec_set=X())
+ self.assertIsInstance(mock, X)
+
+
def test_setting_attribute_with_spec_set(self):
class X(object):
y = 3
@@ -962,15 +985,9 @@ class MockTest(unittest.TestCase):
def assertRaisesWithMsg(self, exception, message, func, *args, **kwargs):
# needed because assertRaisesRegex doesn't work easily with newlines
- try:
+ with self.assertRaises(exception) as context:
func(*args, **kwargs)
- except:
- instance = sys.exc_info()[1]
- self.assertIsInstance(instance, exception)
- else:
- self.fail('Exception {!r} not raised'.format(exception))
-
- msg = str(instance)
+ msg = str(context.exception)
self.assertEqual(msg, message)
@@ -1159,6 +1176,18 @@ class MockTest(unittest.TestCase):
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.assertRegexpMatches(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):
class Subclass(Mock):
pass
@@ -1373,8 +1402,7 @@ class MockTest(unittest.TestCase):
def test_assert_has_calls_with_function_spec(self):
- def f(a, b, c, d=None):
- pass
+ def f(a, b, c, d=None): pass
mock = Mock(spec=f)
@@ -1432,8 +1460,7 @@ class MockTest(unittest.TestCase):
def test_assert_any_call_with_function_spec(self):
- def f(a, b, c, d=None):
- pass
+ def f(a, b, c, d=None): pass
mock = Mock(spec=f)
@@ -1453,8 +1480,7 @@ class MockTest(unittest.TestCase):
def test_mock_calls_create_autospec(self):
- def f(a, b):
- pass
+ def f(a, b): pass
obj = Iter()
obj.f = f
@@ -1479,12 +1505,10 @@ class MockTest(unittest.TestCase):
def test_create_autospec_classmethod_and_staticmethod(self):
class TestClass:
@classmethod
- def class_method(cls):
- pass
+ def class_method(cls): pass
@staticmethod
- def static_method():
- pass
+ def static_method(): pass
for method in ('class_method', 'static_method'):
mock_method = mock.create_autospec(getattr(TestClass, method))
mock_method()
@@ -1909,8 +1933,7 @@ class MockTest(unittest.TestCase):
self.assertEqual(type(call.parent().parent), _Call)
def test_parent_propagation_with_create_autospec(self):
- def foo(a, b):
- pass
+ def foo(a, b): pass
mock = Mock()
mock.child = create_autospec(foo)
@@ -1949,10 +1972,11 @@ class MockTest(unittest.TestCase):
old_patch)
with patch.dict('sys.modules'):
del sys.modules['mock.mock']
- def trace(frame, event, arg):
+ # This trace will stop coverage being measured ;-)
+ def trace(frame, event, arg): # pragma: no cover
return trace
+ self.addCleanup(sys.settrace, sys.gettrace())
sys.settrace(trace)
- self.addCleanup(sys.settrace, None)
from mock.mock import (
Mock, MagicMock, NonCallableMock, NonCallableMagicMock
)
diff --git a/mock/tests/testpatch.py b/mock/tests/testpatch.py
index a7a433e..399961f 100644
--- a/mock/tests/testpatch.py
+++ b/mock/tests/testpatch.py
@@ -47,31 +47,24 @@ something_else = sentinel.SomethingElse
class Foo(object):
- def __init__(self, a):
- pass
- def f(self, a):
- pass
- def g(self):
- pass
+ def __init__(self, a): pass
+ def f(self, a): pass
+ def g(self): pass
foo = 'bar'
@staticmethod
- def static_method():
- return 24
+ def static_method(): pass
@classmethod
- def class_method(cls):
- return 42
+ def class_method(cls): pass
class Bar(object):
- def a(self):
- pass
+ def a(self): pass
foo_name = '%s.Foo' % __name__
-def function(a, b=Foo):
- pass
+def function(a, b=Foo): pass
class Container(object):
@@ -374,31 +367,19 @@ class PatchTest(unittest.TestCase):
def test_patch_wont_create_by_default(self):
- try:
+ with self.assertRaises(AttributeError):
@patch('%s.frooble' % builtin_string, sentinel.Frooble)
- def test():
- self.assertEqual(frooble, sentinel.Frooble)
+ def test(): pass
test()
- except AttributeError:
- pass
- else:
- self.fail('Patching non existent attributes should fail')
-
self.assertRaises(NameError, lambda: frooble)
def test_patchobject_wont_create_by_default(self):
- try:
+ with self.assertRaises(AttributeError):
@patch.object(SomeClass, 'ord', sentinel.Frooble)
- def test():
- self.fail('Patching non existent attributes should fail')
-
+ def test(): pass
test()
- except AttributeError:
- pass
- else:
- self.fail('Patching non existent attributes should fail')
self.assertFalse(hasattr(SomeClass, 'ord'))
@@ -488,6 +469,9 @@ class PatchTest(unittest.TestCase):
attribute = sentinel.Original
class Foo(object):
+
+ test_class_attr = 'whatever'
+
def test_method(other_self, mock_something):
self.assertEqual(PTModule.something, mock_something,
"unpatched")
@@ -646,8 +630,7 @@ class PatchTest(unittest.TestCase):
@patch('%s.SomeClass' % __name__, object(), autospec=True)
@patch.object(SomeClass, object())
@patch.dict(foo)
- def some_name():
- pass
+ def some_name(): pass
self.assertEqual(some_name.__name__, 'some_name')
@@ -658,12 +641,9 @@ class PatchTest(unittest.TestCase):
@patch.dict(foo, {'a': 'b'})
def test():
raise NameError('Konrad')
- try:
+
+ with self.assertRaises(NameError):
test()
- except NameError:
- pass
- else:
- self.fail('NameError not raised by test')
self.assertEqual(foo, {})
@@ -691,49 +671,6 @@ class PatchTest(unittest.TestCase):
support.target = original
- @unittest.expectedFailure
- def test_patch_descriptor(self):
- # would be some effort to fix this - we could special case the
- # builtin descriptors: classmethod, property, staticmethod
- 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):
@patch('%s.SomeClass' % __name__, spec_set=SomeClass)
def test(MockClass):
@@ -933,17 +870,13 @@ class PatchTest(unittest.TestCase):
def test_autospec(self):
class Boo(object):
- def __init__(self, a):
- pass
- def f(self, a):
- pass
- def g(self):
- pass
+ def __init__(self, a): pass
+ def f(self, a): pass
+ def g(self): pass
foo = 'bar'
class Bar(object):
- def a(self):
- pass
+ def a(self): pass
def _test(mock):
mock(1)
@@ -1490,20 +1423,17 @@ class PatchTest(unittest.TestCase):
@patch.object(Foo, 'g', 1)
@patch.object(Foo, 'missing', 1)
@patch.object(Foo, 'f', 1)
- def thing1():
- pass
+ def thing1(): pass
@patch.object(Foo, 'missing', 1)
@patch.object(Foo, 'g', 1)
@patch.object(Foo, 'f', 1)
- def thing2():
- pass
+ def thing2(): pass
@patch.object(Foo, 'g', 1)
@patch.object(Foo, 'f', 1)
@patch.object(Foo, 'missing', 1)
- def thing3():
- pass
+ def thing3(): pass
for func in thing1, thing2, thing3:
self.assertRaises(AttributeError, func)
@@ -1522,20 +1452,17 @@ class PatchTest(unittest.TestCase):
@patch.object(Foo, 'g', 1)
@patch.object(Foo, 'foo', new_callable=crasher)
@patch.object(Foo, 'f', 1)
- def thing1():
- pass
+ def thing1(): pass
@patch.object(Foo, 'foo', new_callable=crasher)
@patch.object(Foo, 'g', 1)
@patch.object(Foo, 'f', 1)
- def thing2():
- pass
+ def thing2(): pass
@patch.object(Foo, 'g', 1)
@patch.object(Foo, 'f', 1)
@patch.object(Foo, 'foo', new_callable=crasher)
- def thing3():
- pass
+ def thing3(): pass
for func in thing1, thing2, thing3:
self.assertRaises(NameError, func)
@@ -1561,8 +1488,7 @@ class PatchTest(unittest.TestCase):
patcher.additional_patchers = additionals
@patcher
- def func():
- pass
+ def func(): pass
self.assertRaises(AttributeError, func)
self.assertEqual(Foo.f, original_f)
@@ -1590,8 +1516,7 @@ class PatchTest(unittest.TestCase):
patcher.additional_patchers = additionals
@patcher
- def func():
- pass
+ def func(): pass
self.assertRaises(NameError, func)
self.assertEqual(Foo.f, original_f)
@@ -1931,5 +1856,35 @@ class PatchTest(unittest.TestCase):
self.assertEqual(foo(), 1)
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 mock.tests.support
+ # now make sure it's not:
+ with patch.dict('sys.modules'):
+ del sys.modules['mock.tests.support']
+ 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):
+ pass
+ test()
+
+
+ def test_invalid_target(self):
+ with self.assertRaises(TypeError):
+ patch('')
+
+
+ def test_cant_set_kwargs_when_passing_a_mock(self):
+ @patch('mock.tests.support.X', new=object(), x=1)
+ def test(): pass
+ with self.assertRaises(TypeError):
+ test()
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/mock/tests/testsealable.py b/mock/tests/testsealable.py
index bd27142..63a8541 100644
--- a/mock/tests/testsealable.py
+++ b/mock/tests/testsealable.py
@@ -3,15 +3,10 @@ import mock
class SampleObject:
- def __init__(self):
- self.attr_sample1 = 1
- self.attr_sample2 = 1
- def method_sample1(self):
- pass
+ def method_sample1(self): pass
- def method_sample2(self):
- pass
+ def method_sample2(self): pass
class TestSealable(unittest.TestCase):
diff --git a/mock/tests/testwith.py b/mock/tests/testwith.py
index ce6e08c..31e8322 100644
--- a/mock/tests/testwith.py
+++ b/mock/tests/testwith.py
@@ -14,6 +14,8 @@ something = sentinel.Something
something_else = sentinel.SomethingElse
+class SampleException(Exception): pass
+
class WithTest(unittest.TestCase):
@@ -24,14 +26,10 @@ class WithTest(unittest.TestCase):
def test_with_statement_exception(self):
- try:
+ with self.assertRaises(SampleException):
with patch('%s.something' % __name__, sentinel.Something2):
self.assertEqual(something, sentinel.Something2, "unpatched")
- raise Exception('pow')
- except Exception:
- pass
- else:
- self.fail("patch swallowed exception")
+ raise SampleException()
self.assertEqual(something, sentinel.Something)
@@ -133,8 +131,7 @@ class WithTest(unittest.TestCase):
def test_double_patch_instance_method(self):
class C:
- def f(self):
- pass
+ def f(self): pass
c = C()