是否可以模拟 Python 3.6 中的内置 len() 函数? [英] Is it possible to mock the builtin len() function in Python 3.6?

查看:59
本文介绍了是否可以模拟 Python 3.6 中的内置 len() 函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以模拟 Python 3.6 中内置的 len() 函数?

Is it possible to mock the builtin len() function in Python 3.6?

我有一个类定义了一个简单的方法,该方法依赖于 len() 函数,如下所示:

I have a class which defines a simple method whic is dependent upon the len() function as follows:

class MyLenFunc(object):
    def is_longer_than_three_characters(self, some_string):
        return len(some_string) > 3

我正在尝试为此方法编写单元测试,但是我无法在不产生错误的情况下模拟 len() 函数.这是我到目前为止所拥有的:

I am trying to write a unit test for this method, but I am unable to mock out the len() function without errors being produced. Here's what I have so far:

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()

我发现了另一个 SO 问题/答案 here 这表明不可能模拟内置函数,因为它们是不可变的.但是,我在这里此处 另有说明.我在上面的单元测试类中的尝试直接来自这些网站中的后者(是的,我已经尝试了那里提到的其他技术.都以相同的错误结束).

I found another SO question/answer here which suggests that it is not possible to mock out builtin functions because they are immutable. However, I found a couple more websites here and here which suggest otherwise. My attempt at the unit test class above is taken directly from the latter of these websites (and yes, I've tried the other techniques mentioned there. All end with the same error).

我收到的错误很长,无法发布完整内容,因此我将删除其中重复的部分(您会看到它是从错误消息的最后部分递归的).错误文本如下:

The error I'm getting is rather long to post the full thing, so I'll snip out the repeating parts of it (you'll see that it's recursive from the final part of the error message). The error text is as follows:

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)

非常感谢.

推荐答案

Don't patch builtins.len;现在mock 库 中的代码中断了,因为它需要函数正常运行!修补被测模块的全局变量:

Don't patch builtins.len; now code in the mock library breaks, because it needs the function to operate as normal! Patch the globals of the module-under-test:

@patch('my_len_func.len')

添加全局len到你的模块,以及MyLenFunc().is_longer_than_three_characters()中的len(some_string)) 方法会找到一个而不是内置函数.

This adds the global len to your module, and the len(some_string) in the MyLenFunc().is_longer_than_three_characters() method will find that one rather than the built-in function.

然而,我必须说,测试 len() 是否被调用感觉是错误的测试.您想检查该方法是否为给定的输入产生了正确的结果,像 len() 这样的基本操作只是实现该目标的小构建块,通常不会在该范围内进行测试.

However, I must say that testing if len() is called feels like the wrong thing to test. You want to check if the method is producing the right results for the given inputs, basic operations like len() are just small building blocks towards that goal and are usually not tested that extent.

这篇关于是否可以模拟 Python 3.6 中的内置 len() 函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆