如何测试可通过环境变量初始化的dataclass?
问题根源
你的测试失败是因为dataclass的默认参数会在类定义阶段(模块被导入时)就计算并固定下来。当你在测试里monkeypatch环境变量时,Example类的host和port默认值已经在导入时用初始环境变量(此时SERVICE_HOST不存在,取了localhost)确定好了,后续修改环境变量不会影响已固定的默认值。
方案1:修改dataclass的默认值定义(推荐)
把默认值改成动态计算的形式,使用dataclasses.field配合default_factory,让每次创建实例时才读取环境变量:
import os import dataclasses @dataclasses.dataclass class Example: host: str = dataclasses.field(default_factory=lambda: os.environ.get('SERVICE_HOST', 'localhost')) port: str = dataclasses.field(default_factory=lambda: os.environ.get('SERVICE_PORT', '30650'))
修改后你原来的测试代码就能正常通过,因为每次实例化Example时才会调用lambda获取当前环境变量的值。
方案2:在测试中先monkeypatch再导入类
如果不想修改dataclass代码,可以调整测试逻辑,先monkeypatch环境变量,再重新导入Example类:
import importlib import os def test_example(monkeypatch): # 设置环境变量 monkeypatch.setenv('SERVICE_HOST', 'server.example.com') monkeypatch.setenv('SERVICE_PORT', '12345') # 重新加载模块,让类定义时读取新的环境变量 import stackoverflow importlib.reload(stackoverflow) Example = stackoverflow.Example # 实例化并断言 example = Example() assert example.host == 'server.example.com' assert example.port == '12345'
这种方式需要注意模块导入顺序,确保monkeypatch之后重新加载模块,让类重新定义时读取新的环境变量。
内容的提问来源于stack exchange,提问作者BioGeek
相关产品推荐
相关产品推荐

