首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用python模拟os.environ

用python模拟os.environ
EN

Stack Overflow用户
提问于 2022-11-29 08:50:42
回答 2查看 52关注 0票数 2

我正在尝试测试一个基于给定参数来处理工作目录的类。为此,我们使用一个类变量来映射它们。

当传递特定值时,将从环境变量中检索路径(参见下面示例中的baz )。这就是我要测试的具体情况。

我正在使用Python 3.8.13unittest

我尽量避免:

  • 我不想嘲弄WorkingDirectory.map字典,因为我想确保我们是用这个特定变量(BAZ_PATH)从environ中提取出来的。
  • 除非是唯一的解决方案,否则我希望避免在测试期间编辑值,也就是说,我不想做这样的事情:os.environ["baz"] = DUMMY_BAZ_PATH

我试过的

我试着按照其他出版物中的建议,把environ模拟成字典,但由于某种原因,我无法使它起作用。

代码语言:javascript
复制
# 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...

测试文件:

代码语言:javascript
复制
# 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时似乎没有得到正确的修补。

代码语言:javascript
复制
======================================================================
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,这导致我认为我确实在做错误的修补工作

代码语言:javascript
复制
AssertionError: '/Users/cestla' != 'path/to/baz'

预期结果

嗯,很明显,我期待test_controlled_baz顺利通过。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-29 09:53:01

所以问题是,您添加了map作为一个静态变量。正如您在这里看到的那样,您的修补程序工作正常:

补丁实际上起作用

问题是当它运行时已经太晚了,因为map变量已经被计算了(在补丁之前)。如果需要,可以将其移动到init函数中,并且它将正确运行:

代码语言:javascript
复制
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]

如果出于某种原因,您希望使其保持静态,则还必须对对象本身进行修补。写这样的东西会有效果:

代码语言:javascript
复制
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)
票数 5
EN

Stack Overflow用户

发布于 2022-11-29 09:00:40

这不是直接回答你的问题,而是一个有效的答案,海事组织:不要试图修补(这是可能的,但更困难和繁琐)。为项目使用配置文件。

例如,使用pyproject.toml并在内部配置pytest扩展:

代码语言:javascript
复制
[tool.pytest.ini_options]
env=[
"SOME_VAR_FOR_TESTS=some_value_for_that_var"
]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74611329

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档