Python 使用mock.patch.dict()在导入的类中修补os.environ
我想对一个类编写一些测试,该类在其Python 使用mock.patch.dict()在导入的类中修补os.environ,python,pytest,Python,Pytest,我想对一个类编写一些测试,该类在其函数中调用os.environ,并想使用mock.patch.dict()调用os.environ。我很确定我在过去成功地做到了这一点,但在这种情况下我无法让它工作 我已对这个问题提出了一份报告。下面是正在测试的类: import os class Widget(): def __init__( self, foo: str = os.environ['SOME_VAR'] ):
函数中调用os.environ
,并想使用mock.patch.dict()
调用os.environ
。我很确定我在过去成功地做到了这一点,但在这种情况下我无法让它工作
我已对这个问题提出了一份报告。下面是正在测试的类:
import os
class Widget():
def __init__(
self,
foo: str = os.environ['SOME_VAR']
):
self.bar = foo
def func1(self):
return self.bar
和我的测试类(在dirtests
中):
我正在使用pytest
作为我的测试运行程序。当我运行测试时,我得到一个错误:
tests/test_widget.py:3:in
从小部件导入小部件
widget.py:4:in
类小部件():
widget.py:7:in widget
foo:str=os.environ['SOME_VAR']
../../../../...virtualenvs/pytest-issue-demo-5A-IlS7_/lib/python3.7/os.py:678:ingetitem
从“无”提升钥匙错误(钥匙)
E键错误:“某些变量”
因此,对os.environ
的调用似乎没有打补丁。不管我怎么努力,我都无法修补它
我的复印件可在以下网址获得:。如果有人能看一下并告诉我如何将调用补丁到os.environ
,以便我能成功运行测试,我将不胜感激
它使用pipenv创建一个virtualenv。假设pipenv和make安装运行
git clone git@github.com:jamiekt/pytest-issue-demo.git
cd pytest-issue-demo
make init test
应该运行测试。对os.environ
的调用是此函数参数列表的一部分,而不是函数体。因此,在加载模块时,表达式os.environ[“SOME_VAR”]
会立即进行计算,因为在导入时会立即发生错误,因此无法在事后进行修补
这是一种糟糕的设计模式,应该避免——函数参数的默认值应该限制在没有副作用的简单表达式中。但是如果您无法更改此代码,那么解决此问题的最简单方法可能是在加载模块时修改“real”os.environ
:
try:
os.environ["SOME_VAR"] = "qwerty"
from widget import Widget
finally:
del os.environ["SOME_VAR"]
(如果您希望环境变量可能已经设置好,那么在保存和恢复其状态时需要更加小心。)对os.environ
的调用是此函数参数列表的一部分,而不是函数体。因此,在加载模块时,表达式os.environ[“SOME_VAR”]
会立即进行计算,因为在导入时会立即发生错误,因此无法在事后进行修补
这是一种糟糕的设计模式,应该避免——函数参数的默认值应该限制在没有副作用的简单表达式中。但是如果您无法更改此代码,那么解决此问题的最简单方法可能是在加载模块时修改“real”os.environ
:
try:
os.environ["SOME_VAR"] = "qwerty"
from widget import Widget
finally:
del os.environ["SOME_VAR"]
(如果您认为环境变量可能已经设置好了,那么在保存和恢复其状态时需要更加小心。)谢谢,这很有效。我也很感激关于更好的设计模式的解释和建议。我将相应地编写真正的代码。谢谢你,这很有效。我也很感激关于更好的设计模式的解释和建议。我将相应地处理真正的代码。