I'm trying to test my Flask APP, but constants which are set inside the Config class using environment variables (os.environ.get()
), aren't overruled by monkeypatching.
My config.py:
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.
"""
# General Config
MY_VARIABLE = environ.get("SOME_ENV_VARIABLE", "somedefault")
My __init__.py
from flask import Flask
from config import Config
def create_app():
app = Flask(__name__, instance_relative_config=False)
app.config.from_object(Config())
My tests/conftest.py
import pytest
from application import create_app
@pytest.fixture(autouse=True)
def env_setup(monkeypatch):
monkeypatch.setenv("SOME_ENV_VARIABLE", "test")
@pytest.fixture()
def app():
app = create_app()
# other setup can go here
yield app
# clean up / reset resources here
My tests/test_config.py:
class TestConfig:
def test_config_values(self, app):
assert app.config.get("MY_VARIABLE") == "test"
I keep getting AssertionError: assert 'somedefault' == 'test'
If I add a method to the config class with a @property decorator, as described at https://flask.palletsprojects.com/en/2.2.x/config/#development-production, then everything seems to work ok, for that specific property. But for class constants, it doesn't. Any thoughts?
CodePudding user response:
There are global variables which are instantiated from the environment at import time. The fixtures are applied after loading the test modules, so they kick in too late.
In other words, this is executed before:
MY_VARIABLE = environ.get("SOME_ENV_VARIABLE", "somedefault")
This is executed after:
monkeypatch.setenv("SOME_ENV_VARIABLE", "test")
There are several way to go around that:
- don't execute
environ.get
at import time - monkeypatch
MY_VARIABLE
instead of"SOME_ENV_VARIABLE"
- mock environment in
pytest_sessionstart
(but don't import the application fromconftest.py
, or it will still be too late)