我正在尝试测试一个基于给定参数来处理工作目录的类。为此,我们使用一个类变量来映射它们。
当传递特定值时,将从环境变量中检索路径(参见下面示例中的baz )。这就是我要测试的具体情况。
我正在使用Python 3.8.13和unittest。
我尽量避免:
WorkingDirectory.map字典,因为我想确保我们是用这个特定变量(BAZ_PATH)从environ中提取出来的。os.environ["baz"] = DUMMY_BAZ_PATH我试过的
我试着按照其他出版物中的建议,把environ模拟成字典,但由于某种原因,我无法使它起作用。
# working_directory.py
import os
class WorkingDirectory:
map = {
"foo": "path/to/foo",
"bar": "path/to/bar",
"baz": os.environ.get("BAZ_PATH"),
}
def __init__(self, env: str):
self.env = env
self.path = self.map[self.env]
@property
def data_dir(self):
return os.path.join(self.path, "data")
# Other similar methods...测试文件:
# test.py
import os
import unittest
from unittest import mock
from working_directory import WorkingDirectory
DUMMY_BAZ_PATH = "path/to/baz"
class TestWorkingDirectory(unittest.TestCase):
@mock.patch.dict(os.environ, {"BAZ_PATH": DUMMY_BAZ_PATH})
def test_controlled_baz(self):
wd = WorkingDirectory("baz")
self.assertEqual(wd.path, DUMMY_BAZ_PATH)错误
正如错误中所示,os.environ在返回Null时似乎没有得到正确的修补。
======================================================================
FAIL: test_controlled_baz (test_directory_structure_utils.TestWorkingDirectory)
----------------------------------------------------------------------
Traceback (most recent call last):
File "~/.pyenv/versions/3.8.13/lib/python3.8/unittest/mock.py", line 1756, in _inner
return f(*args, **kw)
File "~/Projects/dummy_project/tests/unit/test_directory_structure_utils.py", line 127, in test_controlled_baz
self.assertEqual(wd.path, DUMMY_BAZ_PATH)
AssertionError: None != 'path/to/baz'
----------------------------------------------------------------------
Ran 136 tests in 0.325s
FAILED (failures=1, skipped=5)这似乎是因为BAZ_PATH实际上并不存在。不过,我希望这是可以的,因为正在修补。
在映射字典"baz": os.environ.get("BAZ_PATH")中,我为环境中实际存在的变量(即HOME )重新编写了BAZ_PATH,它返回了HOME的实际值,而不是DUMMY_BAZ_PATH,这导致我认为我确实在做错误的修补工作
AssertionError: '/Users/cestla' != 'path/to/baz'预期结果
嗯,很明显,我期待test_controlled_baz顺利通过。
发布于 2022-11-29 09:53:01
所以问题是,您添加了map作为一个静态变量。正如您在这里看到的那样,您的修补程序工作正常:
问题是当它运行时已经太晚了,因为map变量已经被计算了(在补丁之前)。如果需要,可以将其移动到init函数中,并且它将正确运行:
class WorkingDirectory:
def __init__(self, env: str):
self.map = {
"foo": "path/to/foo",
"bar": "path/to/bar",
"baz": os.environ.get("BAZ_PATH")
}
self.env = env
self.path = self.map[self.env]如果出于某种原因,您希望使其保持静态,则还必须对对象本身进行修补。写这样的东西会有效果:
class TestWorkingDirectory(unittest.TestCase):
@mock.patch.dict(os.environ, {"BAZ_PATH": DUMMY_BAZ_PATH})
def test_controlled_baz(self):
with mock.patch.object(WorkingDirectory, "map", {
"foo": "path/to/foo",
"bar": "path/to/bar",
"baz": os.environ.get("BAZ_PATH")
}):
wd = WorkingDirectory("baz")
self.assertEqual(wd.path, DUMMY_BAZ_PATH)发布于 2022-11-29 09:00:40
这不是直接回答你的问题,而是一个有效的答案,海事组织:不要试图修补(这是可能的,但更困难和繁琐)。为项目使用配置文件。
例如,使用pyproject.toml并在内部配置pytest扩展:
[tool.pytest.ini_options]
env=[
"SOME_VAR_FOR_TESTS=some_value_for_that_var"
]https://stackoverflow.com/questions/74611329
复制相似问题