在另一个函数内部导入的函数上打补丁

47 投票
1 回答
22648 浏览
提问于 2025-04-17 20:57

为了避免循环导入,我不得不定义一个看起来像这样的函数:

# do_something.py

def do_it():
    from .helpers import do_it_helper
    # do stuff

现在我想测试这个函数,并且想把do_it_helper替换掉。如果导入是在最上面的地方,

class Test_do_it(unittest.TestCase):
    def test_do_it(self):
        with patch('do_something.do_it_helper') as helper_mock:
            helper_mock.return_value = 12
            # test things

那就没问题了。但是,上面的代码给了我:

AttributeError: <module 'do_something'> does not have the attribute 'do_it_helper'

我一时兴起,也尝试把替换语句改成:

with patch('do_something.do_it.do_it_helper') as helper_mock:

但这也产生了类似的错误。考虑到我被迫在使用这个函数的地方导入它,有没有办法模拟这个函数呢?

1 个回答

62

你应该模拟一下 helpers.do_it_helper 这个函数:

class Test_do_it(unittest.TestCase):
    def test_do_it(self):
        with patch('helpers.do_it_helper') as helper_mock:
            helper_mock.return_value = 12
            # test things

下面是一个使用 mock 来模拟 os.getcwd() 的例子:

import unittest
from mock import patch


def get_cwd():
    from os import getcwd
    return getcwd()


class MyTestCase(unittest.TestCase):
    @patch('os.getcwd')
    def test_mocked(self, mock_function):
        mock_function.return_value = 'test'
        self.assertEqual(get_cwd(), 'test')

撰写回答