如何使用mock的@patch模拟在单独Python模块中定义的函数

10 投票
1 回答
4808 浏览
提问于 2025-04-17 14:28

我正在尝试为一个Python应用程序建立测试,使用的是mock和@patch这个装饰器。

这里有一个目录结构:

  |-- mypackage
  |   |-- mymodule
  |   |   |-- __init__.py
  |   |   \-- somefile.py
  |   \-- myothermodule
  |       |-- tests
  |       |   |-- __init__.py
  |       |   \-- test_func_to_test.py
  |       \-- __init__.py
  \-- __init__.py

这些文件的内容是:


#mypackage/mymodule/somefile.py

def some_function():
    return 'A'

#mypackage/myothermodule/__init__.py

from mypackage.mymodule.somefile import some_function

def func_to_test():
    return some_function()

#mypackage/myothermodule/tests/test_func_to_test.py

from unittest import TestCase
from mock import patch

class TestFunc_to_test(TestCase):
    def test_func_to_test(self):
        from mypackage.myothermodule import func_to_test
        self.assertEqual('A', func_to_test())

    @patch('mypackage.mymodule.somefile.some_function')
    def test_func_to_test_mocked(self, some_mock_function):
        from mypackage.myothermodule import func_to_test
        some_mock_function.return_value = 'B'
        self.assertEqual('B', func_to_test())

我遇到的问题是,第一个测试(test_func_to_test)通过了,但第二个测试(test_func_to_test_mocked)没有通过(出现了AssertionError)。

我已经能够用相同的方法对“内置”模块的函数进行mock(比如requests.get),但是在尝试对我自己模块中的一个函数进行@patch时,却总是搞不定……

任何帮助都将不胜感激 :)

1 个回答

31

已经导入了mypackage.myothermodule,所以在这个模块里,名字some_function已经被定义了。你需要在调用这个名字的模块里模拟它的使用:

@patch('mypackage.myothermodule.some_function')

你也可以选择重新加载mypackage.myothermodule

import mypackage.myothermodule
reload(mypackage.myothermodule)

撰写回答