Проверьте настройки Pydanti c в FastAPI - PullRequest
1 голос
/ 04 мая 2020

Предположим, что мой main.py похож на это (это упрощенный пример, в моем приложении я использую реальную базу данных и имею два разных URI базы данных для разработки и тестирования):

from fastapi import FastAPI
from pydantic import BaseSettings

app = FastAPI()

class Settings(BaseSettings):
    ENVIRONMENT: str

    class Config:
        env_file = ".env"
        case_sensitive = True

settings = Settings()

databases = {
    "dev": "Development",
    "test": "Testing"
}
database = databases[settings.ENVIRONMENT]

@app.get("/")
def read_root():
    return {"Environment": database}

, а .env is

ENVIRONMENT=dev

Предположим, я хочу протестировать свой код и установить ENVIRONMENT=test для использования тестовой базы данных. Что мне делать? В документации FastAPI (https://fastapi.tiangolo.com/advanced/settings/#settings -and-testing ) есть хороший пример, но он касается зависимостей, поэтому, насколько я знаю, это другой случай.

Моя идея была следующее (test.py):

import pytest

from fastapi.testclient import TestClient

from main import app

@pytest.fixture(scope="session", autouse=True)
def test_config(monkeypatch):
    monkeypatch.setenv("ENVIRONMENT", "test")

@pytest.fixture(scope="session")
def client():
    return TestClient(app)

def test_root(client):
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"Environment": "Testing"}

, но оно не работает.

Кроме того, я получаю эту ошибку:

ScopeMismatch: You tried to access the 'function' scoped fixture 'monkeypatch' with a 'session' scoped request object, involved factories
test.py:7:  def test_config(monkeypatch)
env\lib\site-packages\_pytest\monkeypatch.py:16:  def monkeypatch()

в то время как от pytest официальная документация должна работать (https://docs.pytest.org/en/3.0.1/monkeypatch.html#example -setting-a-environment-variable-for-the-test-session * ). У меня установлена ​​последняя версия pytest.

Я пытался использовать определенные c переменные среды тестирования из-за этого: https://pydantic-docs.helpmanual.io/usage/settings/#field -value-priority .

Честно говоря, я заблудился, моя единственная реальная цель - иметь другую тестовую конфигурацию (точно так же Flask работает: https://flask.palletsprojects.com/en/1.1.x/tutorial/tests/#setup -and-fixtures ). Я неправильно подхожу к проблеме?

1 Ответ

0 голосов
/ 05 мая 2020

Действительно сложно смоделировать окружение с участием pydanti c.

Я добился желаемого поведения только путем внедрения зависимостей в fastapi и выполнения функции get_settings, что само по себе кажется хорошей практикой, поскольку даже в документации сказано

Предположим, у вас есть

...

class Settings(BaseSettings):
    ENVIRONMENT: str

    class Config:
        env_file = ".env"
        case_sensitive = True

def get_settings() -> Settings:
    return Settings()

databases = {
    "dev": "Development",
    "test": "Testing"
}
database = databases[get_settings().ENVIRONMENT]

@app.get("/")
def read_root():
    return {"Environment": database}

. В ваших тестах вы должны написать:

import pytest
from main import get_settings

def get_settings_override() -> Settings:
    return Settings(ENVIRONMENT="dev")

@pytest.fixture(autouse=True)
def override_settings() -> None:
    app.dependency_overrides[get_settings] = get_settings_override

Вы можете использовать сессию области, если хотите.

Это переопределит вашу переменную ENVIRONMENT и не коснется остальных переменных конфигурации.

...