首页 > 解决方案 > 如何将 pytest 夹具传递给主函数而不将其添加到参数中?

问题描述

在我的项目中,我有一Settings堂课:

config.py

class Settings(BaseSettings):
    DEBUG: bool = os.getenv("DEBUG", 'False')
    TOKEN_KEY: str = os.getenv("TOKEN_KEY", '')
    TOKEN_PASSWORD: str = os.getenv("TOKEN_PASSWORD", '')


@lru_cache()
def get_settings():
    return Settings()

我以这样的方法使用它:

helpers.py

def generate_new_token(user: User) -> str:
   
    settings = get_settings()
    private_key = settings.TOKEN_KEY
    token_password = settings.TOKEN_PASSWORD
    # Do something

我创建了这两个装置:

conftest.py

@pytest.fixture
def get_settings():
    return Settings(DEBUG=True, TOKEN_KEY="SOME_FAKE_TOKEN_KEY", TOKEN_PASSWORD='')

@pytest.fixture
def get_user():
    return User()

现在我想generate_new_token用从fixtures返回的值来测试这个方法:

test_helpers.py

def test_generate_new_token(get_user, get_settings):
    generate_new_token(user=get_user)

在这种情况下,TOKEN_KEYfrom 的值get_settings应该是SOME_FAKE_TOKEN_KEY,但它仍然是空的。

当我调试代码时,我可以看到它将值从get_settings夹具传递到test_generate_new_token,但随后generate_new_token调用 mainget_settings方法并且不使用夹具中的值get_settings作为settings值。

我知道如果我settings作为参数传递给generate_new_token这样的:

def generate_new_token(user: DexterUser, settings: Settings) -> str:

然后我可以将夹具从测试功能传递给它:

def test_generate_new_token(get_user, get_settings):
    generate_new_token(user=get_user, settings=get_settings)

但是无论如何都可以将夹具传递给主函数而不必将其添加到其参数中?

标签: pythonpytestfixtures

解决方案


您的夹具不会替换功能get_settings,它只是另一种实现。你需要做的是用你自己的补丁实现,例如:

conftest.py

from unittest import mock
import pytest

@pytest.fixture
def get_settings():
    with mock.patch("your_module.helpers.get_settings") as mocked_settings:
        mocked_settings.return_value = Settings(
            DEBUG=True,                                               
            TOKEN_KEY="SOME_FAKE_TOKEN_KEY",                                               
            TOKEN_PASSWORD='')
        yield

请注意,您必须模拟在您的模块get_settings中导入的引用,请参阅在哪里修补.helpers


推荐阅读