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

JPG*_*JPG 2 python unit-testing mocking python-mock python-unittest

长话短说

如何修补或模拟“任何未直接调用/使用的函数”

场景

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

# 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):
        ...
Run Code Online (Sandbox Code Playgroud)

在方法中,我通过调用间接setUp()调用get_user_agents()函数。在此执行过程中,由于尝试访问专用网络,我遇到了异常。那么,在测试过程中如何操作返回数据或整个函数呢?create_foo()socket.timeoutget_user_agents()

get_user_agents

另外,有什么方法可以在整个测试套件执行期间保留这个模拟/补丁吗?

MrB*_*men 6

间接调用该函数并不重要,重要的是在导入该函数时对其进行修补。在您的示例中,您将要在测试函数内部进行本地修补的函数导入,因此它只会在函数运行时导入。在这种情况下,您必须修补从其模块导入的函数(例如'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):
        ...
Run Code Online (Sandbox Code Playgroud)

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

from utils.functions import get_user_agents

def create_foo():
    value = get_user_agents()
    ...
Run Code Online (Sandbox Code Playgroud)

您应该修补导入的实例:

        self.patcher = mock.patch('my_module.tasks.get_user_agents',
                                  return_value='foo')
Run Code Online (Sandbox Code Playgroud)

至于为所有测试修补模块:您可以setUp如上所示开始修补,并在 中停止tearDown