python单元测试中的模拟常量不起作用 [英] Mock constant in python unit test doesn't work
问题描述
我试图在我的 python 单元测试中模拟一个常量.
I'm trying to mock a constant in my python unit test.
我有一个名为 settings.py 的模块,它包含一组常量,特别是我有这个:
I've a module called settings.py which contains a set of constants, in particular I've this one:
REL_PATH = "my/path/{}/file.csv"
然后在另一个模块中我有这个函数,它使用 REL_PATH 变量,如下所示:
Then in another module I've this function which use REL_PATH variable like this:
from path.for.REL_PATH.setting import REL_PATH
def create_csv(missing_path_here):
columns = ["col_a", "col_b", ...]
empty_df = pd.DataFrame(columns=columns)
Writer(empty_df, REL_PATH.format(missing_path_here)).write_csv()
在我的单元测试中,我有以下代码:
In my unit test I've the following code:
class TestCreateAnomaliesRepositoryCsv(unittest.TestCase):
@patch("path.for.setting.REL_PATH", "another/custom/path/file.csv")
def test_create_anomalies_repository_csv(self):
create_csv(missing_path_here="test")
我希望通过这种方式将在another/custom/path/"路径下创建 csv 文件,但仍然在原始目录中创建 csv 文件.
I expect that in this way the csv file will be created under "another/custom/path/" path, but still the csv file is created in the original directory.
我也试过这样做:
def test_create_anomalies_repository_csv(self):
with path("path.for.setting.REL_PATH", "another/custom/path/file.csv")
create_csv(missing_path_here="test")
但最终结果是一样的.
我做错了什么?
推荐答案
如果修补一个对象,您必须始终修补模块中使用的对象,例如如果你在你的模块 module
中以 from x import y
的形式导入它,你必须修补 module.y
而不是 xy
.这在 文档 中有描述,并且有一个很好的Ned Batchelder 的博文更详细地描述了该问题.在您的情况下,您需要:
If patching an object, you have to always patch the object as used in the module, e.g. if you have imported it in the form: from x import y
in your module module
, you have to patch module.y
instead of x.y
. This is described in the documentation, and there is a nice blog post by Ned Batchelder describing the problem in more detail. In your case you need:
@patch("path.to.using_module.REL_PATH", "another/custom/path/file.csv")
def test_create_anomalies_repository_csv(self):
create_csv(missing_path_here="test")
前提是 path.to.using_module.py
像这样导入常量:
provided that path.to.using_module.py
imports the constant like this:
from path.for.setting import REL_PATH
您尝试的另一个变体是等效的,也可以使用:
The other variant you tried is equivalent and will also work:
def test_create_anomalies_repository_csv(self):
with path("path.to.using_module.REL_PATH", "another/custom/path/file.csv")
create_csv(missing_path_here="test")
总而言之,您必须始终检查要使用的对象是如何导入的.基本上有两种情况:
To summarize, you always have to check how the object to use is imported. There are basically two cases:
- 对象在
sut.py
中导入,如import module
或import module.object
- 在这种情况下,它可以被修补为 <代码>module.object - 对象在
sut.py
中导入,就像from module import object
- 在这种情况下sut.py
使用本地引用来引用到对象,并对sut.object
进行修补
- the object is imported in
sut.py
likeimport module
orimport module.object
- in this case it can be patched asmodule.object
- the object is imported in
sut.py
likefrom module import object
- in this casesut.py
uses a local reference to refer to the object, and the patching shall be done forsut.object
这篇关于python单元测试中的模拟常量不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!