Pytest:monkeypatch无法覆盖Flask Config类环境变量问题
问题解决:Flask Config类常量无法被pytest monkeypatch覆盖
问题根源
Config类中的MY_VARIABLE是模块加载阶段就完成赋值的类常量——当Python导入config.py时,environ.get()会立即执行并把结果绑定到MY_VARIABLE上。而pytest的monkeypatch.setenv()是在测试fixture中才执行的,此时config模块早已加载完毕,类常量的值不会再更新。
解决方案
方案1:将配置移至类的__init__方法
修改config.py,把配置属性改为实例化时读取,确保每次创建Config实例时都会获取当前环境变量的值:
from os import environ, path from dotenv import load_dotenv basedir = path.abspath(path.dirname(__file__)) load_dotenv(path.join(basedir, '.env')) class Config: """ Set Flask configuration from environment variables, if present. """ def __init__(self): # General Config self.MY_VARIABLE = environ.get("SOME_ENV_VARIABLE", "somedefault")
你的create_app函数不需要修改,因为app.config.from_object(Config())会读取实例的属性。
方案2:测试时重新加载config模块
在测试fixture中设置完环境变量后,强制重新加载config模块,让类常量重新计算:
修改tests/conftest.py:
import pytest import importlib from application import create_app @pytest.fixture(autouse=True) def env_setup(monkeypatch): monkeypatch.setenv("SOME_ENV_VARIABLE", "test") # 重新加载config模块,刷新类常量的值 import config importlib.reload(config) @pytest.fixture() def app(): app = create_app() yield app
方案3:使用@property延迟读取(已验证可行)
用@property装饰器把类属性改为动态计算的属性,这样每次访问时都会读取当前环境变量:
class Config: @property def MY_VARIABLE(self): return environ.get("SOME_ENV_VARIABLE", "somedefault")
Flask的from_object方法会自动识别并加载@property定义的属性。
内容的提问来源于stack exchange,提问作者Erik van de Ven
相关产品推荐
相关产品推荐

