【问题标题】:Mocking os.environ with python unittests用 python 单元测试模拟 os.environ
【发布时间】:2022-11-29 17:10:54
【问题描述】:

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

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

我正在使用 Python 3.8.13unittest

我试图避免:

  • 我不想模拟 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"),我将BAZ_PATH替换为我环境中实际存在的变量,即HOME,它返回HOME的实际值而不是DUMMY_BAZ_PATH,这导致我认为我肯定在做一些错误的修补

AssertionError: '/Users/cestla' != 'path/to/baz'

预期结果

好吧,显然,我期待test_controlled_baz 成功通过。

【问题讨论】:

    标签: python unit-testing environment-variables python-unittest


    【解决方案1】:

    这不是直接回答你的问题,而是一个有效的答案 imo: 不要试图修补它(这是可能的,但更难和麻烦)。 为您的项目使用配置文件。

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

    [tool.pytest.ini_options]
    env=[
    "SOME_VAR_FOR_TESTS=some_value_for_that_var"
    ]
    

    【讨论】:

      猜你喜欢
      • 2016-09-20
      • 2014-01-29
      • 2017-11-15
      • 2019-05-15
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 2019-10-27
      • 2017-07-03
      相关资源
      最近更新 更多