Python单元测试:mock.patch.dict修改os.environ变量失效问题
Python单元测试mock环境变量失效问题解决
你的问题根源在于被测代码的环境变量读取逻辑是在模块导入阶段执行的,而mock.patch.dict是在测试函数运行时才修改os.environ。当测试用例运行时,被测模块已经提前加载完成,__container__的值在模块导入时就已经确定,后续的mock无法改变这个已经初始化好的值。比如第一个测试用例运行时,模块首次加载读取到mock的"TrUe",设置__container__=True;第二个测试用例运行时,模块已加载完成,不会重新执行模块级代码,导致__container__保持True值,断言失败。
解决方案1:将环境变量读取逻辑封装为函数
把模块级的变量初始化逻辑改成函数,每次需要判断容器状态时调用函数,确保每次都会重新读取环境变量:
修改后的被测代码
#!/usr/bin/env python3 import os def is_container(): env_container = os.getenv('CONTAINER') if env_container is None: return False return env_container.lower() == 'true' # 若需保留__container__变量,可在需要时动态赋值 __container__ = is_container()
修改后的测试代码
@mock.patch.dict(os.environ, {"CONTAINER": "TrUe"}, clear=True) def test_use_container_true(self): self.assertEqual(a.is_container(), True, "not returning python bool True") @mock.patch.dict(os.environ, {"CONTAINER": "fAlSE"}, clear=True) def test_use_container_false(self): self.assertEqual(a.is_container(), False, "not returning python bool False")
如果要保留模块级的__container__变量,也可以将其改为动态属性(比如类的@property),确保每次访问都会重新计算。
解决方案2:测试前重新加载被测模块
在每个测试函数中先卸载已加载的被测模块,再重新导入,强制模块级代码重新执行,读取mock后的环境变量:
修改后的测试代码
import importlib import a # 假设被测模块名为a @mock.patch.dict(os.environ, {"CONTAINER": "TrUe"}, clear=True) def test_use_container_true(self): importlib.reload(a) self.assertEqual(a.__container__, True, "not returning python bool True") @mock.patch.dict(os.environ, {"CONTAINER": "fAlSE"}, clear=True) def test_use_container_false(self): importlib.reload(a) self.assertEqual(a.__container__, False, "not returning python bool False")
内容的提问来源于stack exchange,提问作者jnbdz
相关产品推荐
相关产品推荐

