我如何模拟任何未被直接调用的函数?

How can I mock any function which is not being called directly?

TL;DR

我如何修补或模拟 “任何未直接 called/used 的函数”

场景

我有一个简单的单元测试片段作为

# utils/functions.py
def get_user_agents():
    # sends requests to a private network and pulls data
    return pulled_data


# my_module/tasks.py
def create_foo():
    from utils.functions import get_user_agents
    value = get_user_agents()
    # do something with value
    return some_value


# test.py
class TestFooKlass(unittest.TestCase):
    def setUp(self):
        create_foo()

    def test_foo(self):
        ...

setUp()方法中我调用了get_user_agents()函数通过调用create_foo()间接。在此执行过程中,由于 get_user_agents() 尝试访问专用网络,我遇到了 socket.timeout 异常。

那么,在测试过程中如何操作return数据或整个get_user_agents函数呢?

此外,有什么方法可以在整个测试套件执行期间保持此 mock/patch?

间接调用该函数并不重要 - 重要的是对其进行修补 as it is imported。在您的示例中,您在测试函数中导入了要在本地修补的函数,因此它只会在函数 运行 时导入。在这种情况下,您必须修补从其模块导入的函数(例如 'utils.functions.get_user_agents'):

class TestFooKlass(unittest.TestCase):
    def setUp(self):
        self.patcher = mock.patch('utils.functions.get_user_agents',
                                  return_value='foo')  # whatever it shall return in the test 
        self.patcher.start()  # this returns the patched object, i  case you need it
        create_foo()

    def tearDown(self):
        self.patcher.stop()

    def test_foo(self):
        ...

如果您在模块级别导入了函数,例如:

from utils.functions import get_user_agents

def create_foo():
    value = get_user_agents()
    ...

您应该为导入的实例打补丁:

        self.patcher = mock.patch('my_module.tasks.get_user_agents',
                                  return_value='foo')

至于为所有测试打补丁:您可以在 setUp 开始打补丁,如上所示,并在 tearDown.

停止打补丁。