You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在模块级pytest fixture中正确使用mock_secretsmanager?

解决模块级pytest fixture中mock AWS Secrets Manager的问题

问题现象

在模块级pytest fixture中使用@mock_secretsmanager装饰器创建模拟Secrets Manager秘钥并设置环境变量时,运行测试出现以下错误:

botocore.errorfactory.ResourceNotFoundException: An error occurred (ResourceNotFoundException) when calling the GetSecretValue operation: Secrets Manager can't find the specified secret.

错误代码示例:

@pytest.fixture(scope="module")
def monkeypatch_module():
    # 处理pytest monkeypatch模块级作用域的问题
    from _pytest.monkeypatch import MonkeyPatch

    mpatch = MonkeyPatch()
    yield mpatch
    mpatch.undo()

@pytest.fixture(scope="module")
@mock_secretsmanager
def setup_stuff(monkeypatch_module):
    secret_name = "test_mock_secret01"
    sm_client = boto3.client("secretsmanager", region_name="us-east-1")
    sm_client.create_secret(
        Name=secret_name,
        SecretString='{"username":"mockuser","password":"mockpass"}',
    )
    # 设置模块级环境变量
    monkeypatch_module.setenv("MY_VAR", "sldkfjsdf")

@pytest.mark.unittest
def test__mytest(setup_stuff):
    secret_name = "test_mock_secret01"
    my_method_that_gets_the_secret(secret_name)

临时方案是将setup改为函数在每个测试中调用,但会重复执行模拟操作,不符合模块级fixture一次性执行的需求。

错误原因

@mock_secretsmanager装饰器仅在被装饰的fixture函数执行期间生效,当fixture执行完成后(无yield时直接结束),mock上下文会立即关闭。测试函数运行时,mock已经失效,无法找到之前创建的模拟秘钥。

正确实现方案

使用mock_secretsmanager的上下文管理器形式,配合fixture的yield语法,让mock在整个模块测试周期内保持活跃:

@pytest.fixture(scope="module")
def monkeypatch_module():
    from _pytest.monkeypatch import MonkeyPatch
    mpatch = MonkeyPatch()
    yield mpatch
    mpatch.undo()

@pytest.fixture(scope="module")
def setup_stuff(monkeypatch_module):
    secret_name = "test_mock_secret01"
    # 启动mock上下文并保持至所有模块测试完成
    with mock_secretsmanager():
        # 创建模拟秘钥
        sm_client = boto3.client("secretsmanager", region_name="us-east-1")
        sm_client.create_secret(
            Name=secret_name,
            SecretString='{"username":"mockuser","password":"mockpass"}',
        )
        # 设置模块级环境变量
        monkeypatch_module.setenv("MY_VAR", "sldkfjsdf")
        # 让出执行权,让模块内的测试函数在mock上下文中运行
        yield
    # 退出with块后自动关闭mock

@pytest.mark.unittest
def test__mytest(setup_stuff):
    secret_name = "test_mock_secret01"
    my_method_that_gets_the_secret(secret_name)

关键说明

  • 通过with mock_secretsmanager():手动管理mock的生命周期,确保在模块内所有测试运行期间mock始终生效。
  • fixture中的yield语句会暂停fixture执行,直到模块内所有测试完成后才继续执行with块后续的关闭逻辑,完美匹配模块级作用域的需求。
  • 模块级环境变量通过monkeypatch_module设置,会在所有模块测试完成后统一撤销。

内容的提问来源于stack exchange,提问作者red888

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:45:06