修补在另一个函数中导​​入的函数

Wil*_*uck 19 python testing unit-testing mocking python-unittest

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

# do_something.py

def do_it():
    from .helpers import do_it_helper
    # do stuff
Run Code Online (Sandbox Code Playgroud)

现在我希望能够通过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
Run Code Online (Sandbox Code Playgroud)

会工作得很好.但是,上面的代码给了我:

AttributeError: <module 'do_something'> does not have the attribute 'do_it_helper'
Run Code Online (Sandbox Code Playgroud)

一时兴起,我也尝试将补丁语句更改为:

with patch('do_something.do_it.do_it_helper') as helper_mock:
Run Code Online (Sandbox Code Playgroud)

但这产生了类似的错误.有没有办法模拟这个函数,因为我被迫在它使用的函数中导入它?

ale*_*cxe 34

你应该嘲笑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
Run Code Online (Sandbox Code Playgroud)

这是一个使用mock on的例子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')
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.

  • @alecxe 很抱歉在这么多年后再次提出这个问题。我基本上有与 OP 相同的问题,为什么在其原始文件中而不是在新文件中查找对象?我试图用谷歌搜索它,但每个人都只是轻轻地接触了它——声称它绑定到本地范围,仅此而已。 (4认同)
  • 这完全有效!在哪里打补丁一直让我很困惑。文档中的经验法则是“查找对象的补丁,这不一定与定义它的位置相同。” 但在这种情况下,您可以在定义的地方进行修补。这是为什么? (3认同)
  • 这种行为对我来说仍然清晰如泥。我很高兴这个问题得到了解决,但我对我对这个问题的持续困惑感到遗憾。 (3认同)