是否可以模拟内置len()
Python 3.6 中的函数?
我有一个类定义了一个简单的方法,该方法依赖于len()
函数如下:
class MyLenFunc(object):
def is_longer_than_three_characters(self, some_string):
return len(some_string) > 3
我正在尝试为此方法编写单元测试,但我无法模拟len()
函数不会产生错误。
这是我到目前为止所拥有的:
import unittest
from unittest.mock import patch
import my_len_func
class TestMyLenFunc(unittest.TestCase):
@patch('builtins.len')
def test_len_function_is_called(self, mock_len):
# Arrange
test_string = 'four'
# Act
test_object = my_len_func.MyLenFunc()
test_object.is_longer_than_three_characters(test_string)
# Assert
self.assertEqual(1, mock_len.call_count)
if __name__ == '__main__':
unittest.main()
我发现了另一个问题/答案here https://stackoverflow.com/questions/192649/can-you-monkey-patch-methods-on-core-types-in-python/192857#192857这表明不可能模拟内置函数,因为它们是不可变的。不过,我又发现了几个网站here http://www.voidspace.org.uk/python/mock/examples.html#partial-mocking and here http://www.dsfcode.com/mock-pythons-builtin-functions/这表明情况并非如此。我对上面单元测试类的尝试直接取自这些网站中的后者(是的,我已经尝试了那里提到的其他技术。所有这些都以相同的错误结束)。
我收到的错误相当长,无法发布完整的内容,因此我将剪掉其中的重复部分(您会看到它是从错误消息的最后部分递归的)。错误文本如下:
ERROR: test_len_function_is_called (__main__.TestMyLenFunc)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Python36\Lib\unittest\mock.py", line 1179, in patched
return func(*args, **keywargs)
File "C:/Python/scratchpad/my_len_func_tests.py", line 16, in test_len_function_is_called
test_object.is_longer_than_three_characters(test_string)
File "C:\Python\scratchpad\my_len_func.py", line 3, in is_longer_than_three_characters
return len(some_string) > 3
File "C:\Python36\Lib\unittest\mock.py", line 939, in __call__
return _mock_self._mock_call(*args, **kwargs)
File "C:\Python36\Lib\unittest\mock.py", line 949, in _mock_call
_call = _Call((args, kwargs), two=True)
File "C:\Python36\Lib\unittest\mock.py", line 1972, in __new__
_len = len(value)
...
(Repeat errors from lines 939, 949, and 1972 another 95 times!)
...
File "C:\Python36\Lib\unittest\mock.py", line 939, in __call__
return _mock_self._mock_call(*args, **kwargs)
File "C:\Python36\Lib\unittest\mock.py", line 944, in _mock_call
self.called = True RecursionError: maximum recursion depth exceeded while calling a Python object
----------------------------------------------------------------------
Ran 1 test in 0.004s
FAILED (errors=1)
提前谢谢了。