Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9b21856

Browse files
tirkarthiFelipe
authored andcommitted
bpo-23078: Add support for {class,static}method to mock.create_autospec() (GH-11613)
Co-authored-by: Felipe <[email protected]>
1 parent 9541bd3 commit 9b21856

5 files changed

Lines changed: 81 additions & 2 deletions

File tree

Lib/unittest/mock.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import pprint
3030
import sys
3131
import builtins
32-
from types import ModuleType
32+
from types import ModuleType, MethodType
3333
from unittest.util import safe_repr
3434
from functools import wraps, partial
3535

@@ -122,6 +122,8 @@ def _copy_func_details(func, funcopy):
122122
def _callable(obj):
123123
if isinstance(obj, type):
124124
return True
125+
if isinstance(obj, (staticmethod, classmethod, MethodType)):
126+
return _callable(obj.__func__)
125127
if getattr(obj, '__call__', None) is not None:
126128
return True
127129
return False

Lib/unittest/test/testmock/testhelpers.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from unittest.mock import (
77
call, _Call, create_autospec, MagicMock,
8-
Mock, ANY, _CallList, patch, PropertyMock
8+
Mock, ANY, _CallList, patch, PropertyMock, _callable
99
)
1010

1111
from datetime import datetime
@@ -1011,5 +1011,43 @@ def test_propertymock_returnvalue(self):
10111011
self.assertNotIsInstance(returned, PropertyMock)
10121012

10131013

1014+
class TestCallablePredicate(unittest.TestCase):
1015+
1016+
def test_type(self):
1017+
for obj in [str, bytes, int, list, tuple, SomeClass]:
1018+
self.assertTrue(_callable(obj))
1019+
1020+
def test_call_magic_method(self):
1021+
class Callable:
1022+
def __call__(self):
1023+
pass
1024+
instance = Callable()
1025+
self.assertTrue(_callable(instance))
1026+
1027+
def test_staticmethod(self):
1028+
class WithStaticMethod:
1029+
@staticmethod
1030+
def staticfunc():
1031+
pass
1032+
self.assertTrue(_callable(WithStaticMethod.staticfunc))
1033+
1034+
def test_non_callable_staticmethod(self):
1035+
class BadStaticMethod:
1036+
not_callable = staticmethod(None)
1037+
self.assertFalse(_callable(BadStaticMethod.not_callable))
1038+
1039+
def test_classmethod(self):
1040+
class WithClassMethod:
1041+
@classmethod
1042+
def classfunc(cls):
1043+
pass
1044+
self.assertTrue(_callable(WithClassMethod.classfunc))
1045+
1046+
def test_non_callable_classmethod(self):
1047+
class BadClassMethod:
1048+
not_callable = classmethod(None)
1049+
self.assertFalse(_callable(BadClassMethod.not_callable))
1050+
1051+
10141052
if __name__ == '__main__':
10151053
unittest.main()

Lib/unittest/test/testmock/testmock.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,23 @@ def test_create_autospec_with_name(self):
14191419
m = mock.create_autospec(object(), name='sweet_func')
14201420
self.assertIn('sweet_func', repr(m))
14211421

1422+
#Issue23078
1423+
def test_create_autospec_classmethod_and_staticmethod(self):
1424+
class TestClass:
1425+
@classmethod
1426+
def class_method(cls):
1427+
pass
1428+
1429+
@staticmethod
1430+
def static_method():
1431+
pass
1432+
for method in ('class_method', 'static_method'):
1433+
with self.subTest(method=method):
1434+
mock_method = mock.create_autospec(getattr(TestClass, method))
1435+
mock_method()
1436+
mock_method.assert_called_once_with()
1437+
self.assertRaises(TypeError, mock_method, 'extra_arg')
1438+
14221439
#Issue21238
14231440
def test_mock_unsafe(self):
14241441
m = Mock()

Lib/unittest/test/testmock/testpatch.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ def g(self):
5151
pass
5252
foo = 'bar'
5353

54+
@staticmethod
55+
def static_method():
56+
return 24
57+
58+
@classmethod
59+
def class_method(cls):
60+
return 42
61+
5462
class Bar(object):
5563
def a(self):
5664
pass
@@ -1023,6 +1031,18 @@ def test(mock_function):
10231031
self.assertEqual(result, 3)
10241032

10251033

1034+
def test_autospec_staticmethod(self):
1035+
with patch('%s.Foo.static_method' % __name__, autospec=True) as method:
1036+
Foo.static_method()
1037+
method.assert_called_once_with()
1038+
1039+
1040+
def test_autospec_classmethod(self):
1041+
with patch('%s.Foo.class_method' % __name__, autospec=True) as method:
1042+
Foo.class_method()
1043+
method.assert_called_once_with()
1044+
1045+
10261046
def test_autospec_with_new(self):
10271047
patcher = patch('%s.function' % __name__, new=3, autospec=True)
10281048
self.assertRaises(TypeError, patcher.start)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add support for :func:`classmethod` and :func:`staticmethod` to
2+
:func:`unittest.mock.create_autospec`. Initial patch by Felipe Ochoa.

0 commit comments

Comments
 (0)