summaryrefslogtreecommitdiffstats
path: root/Lib/unittest/test
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2013-02-02 23:23:58 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2013-02-02 23:23:58 (GMT)
commit5c64df70b5b5cf8df2a651dc6630ab28e30499b8 (patch)
tree8bdb8add55c63239f018a0cc2195c8b619bf0a76 /Lib/unittest/test
parent18b30ee88e47ef85ccc966a178bfd8f64a7f0954 (diff)
downloadcpython-5c64df70b5b5cf8df2a651dc6630ab28e30499b8.zip
cpython-5c64df70b5b5cf8df2a651dc6630ab28e30499b8.tar.gz
cpython-5c64df70b5b5cf8df2a651dc6630ab28e30499b8.tar.bz2
Issue #17015: When it has a spec, a Mock object now inspects its signature when matching calls, so that arguments can be matched positionally or by name.
Diffstat (limited to 'Lib/unittest/test')
-rw-r--r--Lib/unittest/test/testmock/testhelpers.py59
-rw-r--r--Lib/unittest/test/testmock/testmock.py125
2 files changed, 164 insertions, 20 deletions
diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/unittest/test/testmock/testhelpers.py
index 8bfb293..8b2e96d 100644
--- a/Lib/unittest/test/testmock/testhelpers.py
+++ b/Lib/unittest/test/testmock/testhelpers.py
@@ -337,9 +337,10 @@ class SpecSignatureTest(unittest.TestCase):
def test_basic(self):
- for spec in (SomeClass, SomeClass()):
- mock = create_autospec(spec)
- self._check_someclass_mock(mock)
+ mock = create_autospec(SomeClass)
+ self._check_someclass_mock(mock)
+ mock = create_autospec(SomeClass())
+ self._check_someclass_mock(mock)
def test_create_autospec_return_value(self):
@@ -576,10 +577,10 @@ class SpecSignatureTest(unittest.TestCase):
def test_spec_inheritance_for_classes(self):
class Foo(object):
- def a(self):
+ def a(self, x):
pass
class Bar(object):
- def f(self):
+ def f(self, y):
pass
class_mock = create_autospec(Foo)
@@ -587,26 +588,30 @@ class SpecSignatureTest(unittest.TestCase):
self.assertIsNot(class_mock, class_mock())
for this_mock in class_mock, class_mock():
- this_mock.a()
- this_mock.a.assert_called_with()
- self.assertRaises(TypeError, this_mock.a, 'foo')
+ this_mock.a(x=5)
+ this_mock.a.assert_called_with(x=5)
+ this_mock.a.assert_called_with(5)
+ self.assertRaises(TypeError, this_mock.a, 'foo', 'bar')
self.assertRaises(AttributeError, getattr, this_mock, 'b')
instance_mock = create_autospec(Foo())
- instance_mock.a()
- instance_mock.a.assert_called_with()
- self.assertRaises(TypeError, instance_mock.a, 'foo')
+ instance_mock.a(5)
+ instance_mock.a.assert_called_with(5)
+ instance_mock.a.assert_called_with(x=5)
+ self.assertRaises(TypeError, instance_mock.a, 'foo', 'bar')
self.assertRaises(AttributeError, getattr, instance_mock, 'b')
# The return value isn't isn't callable
self.assertRaises(TypeError, instance_mock)
- instance_mock.Bar.f()
- instance_mock.Bar.f.assert_called_with()
+ instance_mock.Bar.f(6)
+ instance_mock.Bar.f.assert_called_with(6)
+ instance_mock.Bar.f.assert_called_with(y=6)
self.assertRaises(AttributeError, getattr, instance_mock.Bar, 'g')
- instance_mock.Bar().f()
- instance_mock.Bar().f.assert_called_with()
+ instance_mock.Bar().f(6)
+ instance_mock.Bar().f.assert_called_with(6)
+ instance_mock.Bar().f.assert_called_with(y=6)
self.assertRaises(AttributeError, getattr, instance_mock.Bar(), 'g')
@@ -663,12 +668,15 @@ class SpecSignatureTest(unittest.TestCase):
self.assertRaises(TypeError, mock)
mock(1, 2)
mock.assert_called_with(1, 2)
+ mock.assert_called_with(1, b=2)
+ mock.assert_called_with(a=1, b=2)
f.f = f
mock = create_autospec(f)
self.assertRaises(TypeError, mock.f)
mock.f(3, 4)
mock.f.assert_called_with(3, 4)
+ mock.f.assert_called_with(a=3, b=4)
def test_skip_attributeerrors(self):
@@ -704,9 +712,13 @@ class SpecSignatureTest(unittest.TestCase):
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)
mock(4, 5)
mock.assert_called_with(4, 5)
+ mock.assert_called_with(a=4, b=5)
+ self.assertRaises(AssertionError, mock.assert_called_with, a=5, b=4)
def test_class_with_no_init(self):
@@ -719,24 +731,27 @@ class SpecSignatureTest(unittest.TestCase):
def test_signature_callable(self):
class Callable(object):
- def __init__(self):
+ def __init__(self, x, y):
pass
def __call__(self, a):
pass
mock = create_autospec(Callable)
- mock()
- mock.assert_called_once_with()
+ mock(1, 2)
+ mock.assert_called_once_with(1, 2)
+ mock.assert_called_once_with(x=1, y=2)
self.assertRaises(TypeError, mock, 'a')
- instance = mock()
+ instance = mock(1, 2)
self.assertRaises(TypeError, instance)
instance(a='a')
+ instance.assert_called_once_with('a')
instance.assert_called_once_with(a='a')
instance('a')
instance.assert_called_with('a')
+ instance.assert_called_with(a='a')
- mock = create_autospec(Callable())
+ mock = create_autospec(Callable(1, 2))
mock(a='a')
mock.assert_called_once_with(a='a')
self.assertRaises(TypeError, mock)
@@ -779,7 +794,11 @@ class SpecSignatureTest(unittest.TestCase):
pass
a = create_autospec(Foo)
+ a.f(10)
+ a.f.assert_called_with(10)
+ a.f.assert_called_with(self=10)
a.f(self=10)
+ a.f.assert_called_with(10)
a.f.assert_called_with(self=10)
diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/unittest/test/testmock/testmock.py
index 2c6f128..475a826 100644
--- a/Lib/unittest/test/testmock/testmock.py
+++ b/Lib/unittest/test/testmock/testmock.py
@@ -25,6 +25,18 @@ class Iter(object):
__next__ = next
+class Something(object):
+ def meth(self, a, b, c, d=None):
+ pass
+
+ @classmethod
+ def cmeth(cls, a, b, c, d=None):
+ pass
+
+ @staticmethod
+ def smeth(a, b, c, d=None):
+ pass
+
class MockTest(unittest.TestCase):
@@ -273,6 +285,43 @@ class MockTest(unittest.TestCase):
mock.assert_called_with(1, 2, 3, a='fish', b='nothing')
+ def test_assert_called_with_function_spec(self):
+ def f(a, b, c, d=None):
+ pass
+
+ mock = Mock(spec=f)
+
+ mock(1, b=2, c=3)
+ mock.assert_called_with(1, 2, 3)
+ mock.assert_called_with(a=1, b=2, c=3)
+ self.assertRaises(AssertionError, mock.assert_called_with,
+ 1, b=3, c=2)
+ # Expected call doesn't match the spec's signature
+ with self.assertRaises(AssertionError) as cm:
+ mock.assert_called_with(e=8)
+ self.assertIsInstance(cm.exception.__cause__, TypeError)
+
+
+ def test_assert_called_with_method_spec(self):
+ def _check(mock):
+ mock(1, b=2, c=3)
+ mock.assert_called_with(1, 2, 3)
+ mock.assert_called_with(a=1, b=2, c=3)
+ self.assertRaises(AssertionError, mock.assert_called_with,
+ 1, b=3, c=2)
+
+ mock = Mock(spec=Something().meth)
+ _check(mock)
+ mock = Mock(spec=Something.cmeth)
+ _check(mock)
+ mock = Mock(spec=Something().cmeth)
+ _check(mock)
+ mock = Mock(spec=Something.smeth)
+ _check(mock)
+ mock = Mock(spec=Something().smeth)
+ _check(mock)
+
+
def test_assert_called_once_with(self):
mock = Mock()
mock()
@@ -297,6 +346,29 @@ class MockTest(unittest.TestCase):
)
+ def test_assert_called_once_with_function_spec(self):
+ def f(a, b, c, d=None):
+ pass
+
+ mock = Mock(spec=f)
+
+ mock(1, b=2, c=3)
+ mock.assert_called_once_with(1, 2, 3)
+ mock.assert_called_once_with(a=1, b=2, c=3)
+ self.assertRaises(AssertionError, mock.assert_called_once_with,
+ 1, b=3, c=2)
+ # Expected call doesn't match the spec's signature
+ with self.assertRaises(AssertionError) as cm:
+ mock.assert_called_once_with(e=8)
+ self.assertIsInstance(cm.exception.__cause__, TypeError)
+ # Mock called more than once => always fails
+ mock(4, 5, 6)
+ self.assertRaises(AssertionError, mock.assert_called_once_with,
+ 1, 2, 3)
+ self.assertRaises(AssertionError, mock.assert_called_once_with,
+ 4, 5, 6)
+
+
def test_attribute_access_returns_mocks(self):
mock = Mock()
something = mock.something
@@ -991,6 +1063,39 @@ class MockTest(unittest.TestCase):
)
+ def test_assert_has_calls_with_function_spec(self):
+ def f(a, b, c, d=None):
+ pass
+
+ mock = Mock(spec=f)
+
+ mock(1, b=2, c=3)
+ mock(4, 5, c=6, d=7)
+ mock(10, 11, c=12)
+ calls = [
+ ('', (1, 2, 3), {}),
+ ('', (4, 5, 6), {'d': 7}),
+ ((10, 11, 12), {}),
+ ]
+ mock.assert_has_calls(calls)
+ mock.assert_has_calls(calls, any_order=True)
+ mock.assert_has_calls(calls[1:])
+ mock.assert_has_calls(calls[1:], any_order=True)
+ mock.assert_has_calls(calls[:-1])
+ mock.assert_has_calls(calls[:-1], any_order=True)
+ # Reversed order
+ calls = list(reversed(calls))
+ with self.assertRaises(AssertionError):
+ mock.assert_has_calls(calls)
+ mock.assert_has_calls(calls, any_order=True)
+ with self.assertRaises(AssertionError):
+ mock.assert_has_calls(calls[1:])
+ mock.assert_has_calls(calls[1:], any_order=True)
+ with self.assertRaises(AssertionError):
+ mock.assert_has_calls(calls[:-1])
+ mock.assert_has_calls(calls[:-1], any_order=True)
+
+
def test_assert_any_call(self):
mock = Mock()
mock(1, 2)
@@ -1017,6 +1122,26 @@ class MockTest(unittest.TestCase):
)
+ def test_assert_any_call_with_function_spec(self):
+ def f(a, b, c, d=None):
+ pass
+
+ mock = Mock(spec=f)
+
+ mock(1, b=2, c=3)
+ mock(4, 5, c=6, d=7)
+ mock.assert_any_call(1, 2, 3)
+ mock.assert_any_call(a=1, b=2, c=3)
+ mock.assert_any_call(4, 5, 6, 7)
+ mock.assert_any_call(a=4, b=5, c=6, d=7)
+ self.assertRaises(AssertionError, mock.assert_any_call,
+ 1, b=3, c=2)
+ # Expected call doesn't match the spec's signature
+ with self.assertRaises(AssertionError) as cm:
+ mock.assert_any_call(e=8)
+ self.assertIsInstance(cm.exception.__cause__, TypeError)
+
+
def test_mock_calls_create_autospec(self):
def f(a, b):
pass