summaryrefslogtreecommitdiff
path: root/mock/tests/testhelpers.py
diff options
context:
space:
mode:
Diffstat (limited to 'mock/tests/testhelpers.py')
-rw-r--r--mock/tests/testhelpers.py215
1 files changed, 133 insertions, 82 deletions
diff --git a/mock/tests/testhelpers.py b/mock/tests/testhelpers.py
index 2a28796..d56a47f 100644
--- a/mock/tests/testhelpers.py
+++ b/mock/tests/testhelpers.py
@@ -1,6 +1,12 @@
+# Copyright (C) 2007-2012 Michael Foord & the mock team
+# E-mail: fuzzyman AT voidspace DOT org DOT uk
+# http://www.voidspace.org.uk/python/mock/
+import socket
+
import inspect
+import six
+import sys
import time
-import types
import unittest
from mock import (
@@ -8,12 +14,13 @@ from mock import (
Mock, ANY, patch, PropertyMock
)
from mock.mock import _Call, _CallList, _callable
-from mock import IS_PYPY
from datetime import datetime
from functools import partial
-import pytest
+
+if six.PY2:
+ import funcsigs
class SomeClass(object):
@@ -22,6 +29,7 @@ class SomeClass(object):
def three(self, a=None): pass
+
class AnyTest(unittest.TestCase):
def test_any(self):
@@ -68,28 +76,7 @@ class AnyTest(unittest.TestCase):
self.assertEqual(expected, mock.mock_calls)
self.assertEqual(mock.mock_calls, expected)
- def test_any_no_spec(self):
- # This is a regression test for bpo-37555
- class Foo:
- def __eq__(self, other): pass
-
- mock = Mock()
- mock(Foo(), 1)
- mock.assert_has_calls([call(ANY, 1)])
- mock.assert_called_with(ANY, 1)
- mock.assert_any_call(ANY, 1)
-
- def test_any_and_spec_set(self):
- # This is a regression test for bpo-37555
- class Foo:
- def __eq__(self, other): pass
-
- mock = Mock(spec=Foo)
- mock(Foo(), 1)
- mock.assert_has_calls([call(ANY, 1)])
- mock.assert_called_with(ANY, 1)
- mock.assert_any_call(ANY, 1)
class CallTest(unittest.TestCase):
@@ -359,26 +346,6 @@ class CallTest(unittest.TestCase):
self.assertEqual(_Call((('bar', 'barz'),),)[0], '')
self.assertEqual(_Call((('bar', 'barz'), {'hello': 'world'}),)[0], '')
- def test_dunder_call(self):
- m = MagicMock()
- m().foo()['bar']()
- self.assertEqual(
- m.mock_calls,
- [call(), call().foo(), call().foo().__getitem__('bar'), call().foo().__getitem__()()]
- )
- m = MagicMock()
- m().foo()['bar'] = 1
- self.assertEqual(
- m.mock_calls,
- [call(), call().foo(), call().foo().__setitem__('bar', 1)]
- )
- m = MagicMock()
- iter(m().foo())
- self.assertEqual(
- m.mock_calls,
- [call(), call().foo(), call().foo().__iter__()]
- )
-
class SpecSignatureTest(unittest.TestCase):
@@ -451,9 +418,12 @@ class SpecSignatureTest(unittest.TestCase):
m = create_autospec(Foo, a='3')
self.assertEqual(m.a, '3')
-
+ @unittest.skipUnless(six.PY3, "Keyword only arguments Python 3 specific")
def test_create_autospec_keyword_only_arguments(self):
- def foo(a, *, b=None): pass
+ func_def = "def foo(a, *, b=None): pass\n"
+ namespace = {}
+ exec (func_def, namespace)
+ foo = namespace['foo']
m = create_autospec(foo)
m(1)
@@ -463,7 +433,6 @@ class SpecSignatureTest(unittest.TestCase):
m(2, b=3)
m.assert_called_with(2, b=3)
-
def test_function_as_instance_attribute(self):
obj = SomeClass()
def f(a): pass
@@ -502,16 +471,16 @@ class SpecSignatureTest(unittest.TestCase):
self._check_someclass_mock(mock)
+ @unittest.skipIf('PyPy' in sys.version,
+ "This fails on pypy, "
+ "see https://github.com/testing-cabal/mock/issues/452")
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)
@@ -521,13 +490,11 @@ class SpecSignatureTest(unittest.TestCase):
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']
+ return super(CrazyClass, self).__dir__() + ['crazy']
def __getattr__(self, item):
if item == 'crazy':
@@ -538,7 +505,6 @@ class SpecSignatureTest(unittest.TestCase):
with self.assertRaises(AttributeError):
inst.other
self.assertEqual(inst.crazy(42), 42)
-
mock = create_autospec(inst)
mock.crazy(42)
with self.assertRaises(TypeError):
@@ -547,6 +513,8 @@ class SpecSignatureTest(unittest.TestCase):
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):
# we could replace builtin functions / methods with a function
# with *args / **kwargs signature. Using the builtin method type
@@ -643,6 +611,27 @@ class SpecSignatureTest(unittest.TestCase):
mock.g.assert_called_once_with(3, 4)
+ @unittest.skipIf(six.PY3, "No old style classes in Python 3")
+ def test_old_style_classes(self):
+ class Foo:
+ def f(self, a, b): pass
+
+ class Bar(Foo):
+ g = Foo()
+
+ for spec in (Foo, Foo(), Bar, Bar()):
+ mock = create_autospec(spec)
+ mock.f(1, 2)
+ mock.f.assert_called_once_with(1, 2)
+
+ self.assertRaises(AttributeError, getattr, mock, 'foo')
+ self.assertRaises(AttributeError, getattr, mock.f, 'foo')
+
+ mock.g.f(1, 2)
+ mock.g.f.assert_called_once_with(1, 2)
+ self.assertRaises(AttributeError, getattr, mock.g, 'foo')
+
+
def test_recursive(self):
class A(object):
def a(self): pass
@@ -799,6 +788,21 @@ class SpecSignatureTest(unittest.TestCase):
self.assertRaises(TypeError, mock)
mock(1)
mock.assert_called_once_with(1)
+
+ mock(4, 5)
+ mock.assert_called_with(4, 5)
+
+
+ @unittest.skipIf(six.PY3, 'no old style classes in Python 3')
+ def test_signature_old_style_class(self):
+ class Foo:
+ def __init__(self, a, b=3): pass
+
+ mock = create_autospec(Foo)
+
+ self.assertRaises(TypeError, mock)
+ mock(1)
+ mock.assert_called_once_with(1)
mock.assert_called_once_with(a=1)
self.assertRaises(AssertionError, mock.assert_called_once_with, 2)
@@ -816,6 +820,15 @@ class SpecSignatureTest(unittest.TestCase):
create_autospec(Foo)
+ @unittest.skipIf(six.PY3, 'no old style classes in Python 3')
+ def test_old_style_class_with_no_init(self):
+ # this used to raise an exception
+ # due to Foo.__init__ raising an AttributeError
+ class Foo:
+ pass
+ create_autospec(Foo)
+
+
def test_signature_callable(self):
class Callable(object):
def __init__(self, x, y): pass
@@ -886,6 +899,36 @@ class SpecSignatureTest(unittest.TestCase):
a.f.assert_called_with(self=10)
+ def test_autospec_property(self):
+ class Foo(object):
+ @property
+ def foo(self): pass
+
+ foo = create_autospec(Foo)
+ mock_property = foo.foo
+
+ # no spec on properties
+ self.assertIsInstance(mock_property, MagicMock)
+ mock_property(1, 2, 3)
+ mock_property.abc(4, 5, 6)
+ mock_property.assert_called_once_with(1, 2, 3)
+ mock_property.abc.assert_called_once_with(4, 5, 6)
+
+
+ def test_autospec_slots(self):
+ class Foo(object):
+ __slots__ = ['a']
+
+ foo = create_autospec(Foo)
+ mock_slot = foo.a
+
+ # no spec on slots
+ mock_slot(1, 2, 3)
+ mock_slot.abc(4, 5, 6)
+ mock_slot.assert_called_once_with(1, 2, 3)
+ mock_slot.abc.assert_called_once_with(4, 5, 6)
+
+
def test_autospec_data_descriptor(self):
class Descriptor(object):
def __init__(self, value):
@@ -930,8 +973,10 @@ class SpecSignatureTest(unittest.TestCase):
check_data_descriptor(foo.desc)
+ @unittest.skipIf('PyPy' in sys.version and sys.version_info > (3, 0),
+ "See https://github.com/testing-cabal/mock/issues/452")
def test_autospec_on_bound_builtin_function(self):
- meth = types.MethodType(time.ctime, time.time())
+ meth = six.create_bound_method(time.ctime, time.time())
self.assertIsInstance(meth(), str)
mocked = create_autospec(meth)
@@ -939,23 +984,20 @@ class SpecSignatureTest(unittest.TestCase):
mocked()
mocked.assert_called_once_with()
mocked.reset_mock()
- # but pypy gets this right:
- if IS_PYPY:
- with self.assertRaises(TypeError):
- mocked(4, 5, 6)
- else:
- mocked(4, 5, 6)
- mocked.assert_called_once_with(4, 5, 6)
+ mocked(4, 5, 6)
+ mocked.assert_called_once_with(4, 5, 6)
+
+ def test_autospec_socket(self):
+ sock_class = create_autospec(socket.socket)
+ self.assertRaises(TypeError, sock_class, foo=1)
def test_autospec_getattr_partial_function(self):
# bpo-32153 : getattr returning partial functions without
# __name__ should not create AttributeError in create_autospec
- class Foo:
-
+ class Foo(object):
def __getattr__(self, attribute):
return partial(lambda name: name, attribute)
-
proxy = Foo()
autospec = create_autospec(proxy)
self.assertFalse(hasattr(autospec, '__name__'))
@@ -969,29 +1011,24 @@ class SpecSignatureTest(unittest.TestCase):
mock(1, 2)
mock(x=1, y=2)
- self.assertEqual(inspect.signature(mock), inspect.signature(myfunc))
+ if six.PY2:
+ self.assertEqual(funcsigs.signature(mock), funcsigs.signature(myfunc))
+ else:
+ self.assertEqual(inspect.getfullargspec(mock), inspect.getfullargspec(myfunc))
self.assertEqual(mock.mock_calls, [call(1, 2), call(x=1, y=2)])
self.assertRaises(TypeError, mock, 1)
- def test_spec_inspect_signature_annotations(self):
-
- 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)
-
- self.assertEqual(inspect.signature(mock), inspect.signature(foo))
- self.assertEqual(mock.mock_calls, [call(1, 2, c=3), call(1, c=3)])
- self.assertRaises(TypeError, mock, 1)
- 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_no_name(self):
+ @unittest.skipIf(six.PY3, "Here to test our Py2 _isidentifier")
+ def test_spec_function_has_identifier_name(self):
func = lambda: 'nope'
+ func.__name__ = 'global'
mock = create_autospec(func)
self.assertEqual(mock.__name__, 'funcopy')
@@ -1068,6 +1105,20 @@ class TestCallList(unittest.TestCase):
self.assertEqual(str(mock.mock_calls), expected)
+ @unittest.skipIf(six.PY3, "Unicode is properly handled with Python 3")
+ def test_call_list_unicode(self):
+ # See github issue #328
+ mock = Mock()
+
+ class NonAsciiRepr(object):
+ def __repr__(self):
+ return "\xe9"
+
+ mock(**{unicode("a"): NonAsciiRepr()})
+
+ self.assertEqual(str(mock.mock_calls), "[call(a=\xe9)]")
+
+
def test_propertymock(self):
p = patch('%s.SomeClass.one' % __name__, new_callable=PropertyMock)
mock = p.start()