未调用python模拟函数

未调用python模拟函数,python,mocking,python-unittest,python-unittest.mock,Python,Mocking,Python Unittest,Python Unittest.mock,我正在测试python代码(一个django 3.0.5项目,尽管我不认为这与此相关),但我无法调用模拟对象的函数。这是我的密码: **myproject.mypackage.myhelpers** def get_dict(): return dict() **myproject.mypackage.mythings** from .myhelpers import get_dict def use_dict(): the_dict = get_dict()

我正在测试python代码(一个django 3.0.5项目,尽管我不认为这与此相关),但我无法调用模拟对象的函数。这是我的密码:

**myproject.mypackage.myhelpers**


def get_dict():
    return dict()

**myproject.mypackage.mythings**

from .myhelpers import get_dict


def use_dict():
    the_dict = get_dict()
    pass
    return


**myproject.tests.test_mythings**

from ..mypackage import mythings
import unittest
import unittest.mock as mock


class MyThingsTests(unittest.TestCase):

    @mock.patch('myproject.mypackage.myhelpers')
    def test_using_dict(self, mock_myhelpers):
        test_dict = {
            "hi": "foo",
            "there": "bar",
            "sir": "foobar"
        }

        mock_myhelpers.get_dict.return_value = test_dict

        mythings.use_dict()

        mock_myhelpers.get_dict.assert_called_once()
但最终测试失败,出现错误:

AssertionError:预期“get_dict”已被调用一次。调用了0次

请尝试以下操作:

@mock.patch('myproject.mypackage.mythings.get_dict')
def test_using_dict(self, mock_get_dict):
    test_dict = {
        "hi": "foo",
        "there": "bar",
        "sir": "foobar"
    }

    mock_get_dict.return_value = test_dict
文档的这一部分对此做了一些解释

从我的理解来看,
myproject.mypackage.mythings
在你做补丁之前已经导入了“真实的”
get_dict
。因此,如果您像
@mock.patch('myproject.mypackage.myhelpers')
那样对其进行修补,则只有
myhelpers
模块才会“知道”它已修补。
mythings
模块仍将引用真实的
get\u dict


我认为,我上面所做的修补方法的另一种替代方法是更改导入
get_dict
的方式。不要直接导入
get_dict
,只需导入
myhelpers
并将
get_dict
用作
myhelpers.get_dict
。然后你应该能够保持你的补丁方式不变,因为
get_dict
将从
myhelpers
中查找,这将使用补丁方法。

你完全正确!或者,至少你的建议通过了测试,这就是答案。我想补充一点,在考虑修补时,必须考虑执行期间的导入,而不是它们的编写方式。当您为测试
module\u b
module\u b
中有一个
从module\u a导入方法\u a
而修补
@patch('module\u b.method\u a')时,您需要的修补程序是
@patch('module\u b.method\u a')