python 未调用模拟函数
python mocked function not called
我正在测试 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: Expected 'get_dict' to have been called once. Called 0 times
试试这个:
@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
文档的 Where to patch 部分对其进行了一些解释。
根据我的理解,myproject.mypackage.mythings
在你打补丁之前已经导入了“真正的”get_dict
。因此,如果您像 @mock.patch('myproject.mypackage.myhelpers')
那样修补它,只有 myhelpers
模块会“知道”它已被修补。 mythings
模块仍然会引用真正的 get_dict
.
我认为我上面做的修补方式的替代方法是更改导入方式 get_dict
。不要直接导入 get_dict
,只需导入 myhelpers
并将 get_dict
用作 myhelpers.get_dict
。然后你应该能够保持你的修补方式相同,因为 get_dict
将从具有修补方法的 myhelpers
中查找。
解决方案 1
- 将
myproject.mypackage.myhelpers
替换为myproject.mypackage.mythings
# @mock.patch('myproject.mypackage.myhelpers')
@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
解决方案 2
- 将
from .myhelpers import get_dict
替换为import .myhelpers as helpers
**myproject.mypackage.mythings**
# from .myhelpers import get_dict
import .myhelpers as helpers
def use_dict():
the_dict = helpers.get_dict()
pass
return
总结
- 解决方案 1 更好,因为它不会打扰您更新所有
.py
文件中的 import
样式
我正在测试 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: Expected 'get_dict' to have been called once. Called 0 times
试试这个:
@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
文档的 Where to patch 部分对其进行了一些解释。
根据我的理解,myproject.mypackage.mythings
在你打补丁之前已经导入了“真正的”get_dict
。因此,如果您像 @mock.patch('myproject.mypackage.myhelpers')
那样修补它,只有 myhelpers
模块会“知道”它已被修补。 mythings
模块仍然会引用真正的 get_dict
.
我认为我上面做的修补方式的替代方法是更改导入方式 get_dict
。不要直接导入 get_dict
,只需导入 myhelpers
并将 get_dict
用作 myhelpers.get_dict
。然后你应该能够保持你的修补方式相同,因为 get_dict
将从具有修补方法的 myhelpers
中查找。
解决方案 1
- 将
myproject.mypackage.myhelpers
替换为myproject.mypackage.mythings
# @mock.patch('myproject.mypackage.myhelpers')
@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
解决方案 2
- 将
from .myhelpers import get_dict
替换为import .myhelpers as helpers
**myproject.mypackage.mythings**
# from .myhelpers import get_dict
import .myhelpers as helpers
def use_dict():
the_dict = helpers.get_dict()
pass
return
总结
- 解决方案 1 更好,因为它不会打扰您更新所有
.py
文件中的import
样式