如何模拟任何未被直接调用的函数? [英] How can I mock any function which is not being called directly?

查看:54
本文介绍了如何模拟任何未被直接调用的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何修补或模拟任何未被直接调用/使用的函数"?

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

I have a simple unit-test snippet as

# 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 异常.

那么,如何在测试期间操作返回数据或整个 get_user_agents 函数?

另外,有没有办法在整个测试套件执行过程中保留这个模拟/补丁?

Also, is there any way to persists this mock/patch during the whole test suite execution?

推荐答案

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

It does not matter that you call the function indirectly - important is to patch it as it is imported. In your example you import the function to be patched locally inside the tested function, so it will only be imported at function run time. In this case you have to patch the function as imported from its module (e.g. '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):
        ...

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

If you had imported the function instead at module level like:

from utils.functions import get_user_agents

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

您应该修补导入的实例:

you should have patched the imported instance instead:

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

对于所有测试的模块打补丁:可以如上图在setUp中开始打补丁,在tearDown中停止.

As for patching the module for all tests: you can start patching in setUp as shown above, and stop it in tearDown.

这篇关于如何模拟任何未被直接调用的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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