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

函数外定义AWS/boto3客户端/资源,单元测试认证失败求解决方案

解决方案

方法1:懒加载单例模式

将客户端初始化改为懒加载逻辑,只有第一次调用函数时才创建客户端实例。这样在测试时,mock环境已经准备完毕,客户端会使用模拟凭证创建,避免连接真实AWS。

import boto3

class SecretsManagerClient:
    _instance = None

    @classmethod
    def get_instance(cls):
        if cls._instance is None:
            cls._instance = boto3.client(service_name="secretsmanager")
        return cls._instance

def get_secret_key_string():
    sm_client = SecretsManagerClient.get_instance()
    return sm_client.get_secret_value(SecretId="my_key")["SecretString"]

方法2:测试时重置单例实例

如果使用单例模式,可在测试fixture中主动重置单例的实例,确保每次测试都基于mock环境创建新的客户端,避免残留的真实客户端影响测试。

修改后的 conftest.py:

import os
import pytest
from moto import mock_secretsmanager
from my_module import SecretsManagerClient  # 导入你的单例类

@pytest.fixture(scope="session", autouse=True)
def aws_credentials():
    """Mocked AWS Credentials for moto"""
    os.environ["AWS_ACCESS_KEY_ID"] = "testing"
    os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
    os.environ["AWS_SECURITY_TOKEN"] = "testing"
    os.environ["AWS_SESSION_TOKEN"] = "testing"
    os.environ["AWS_DEFAULT_REGION"] = "us-east-1"

@pytest.fixture(scope="function")
def secrets_client(aws_credentials):
    with mock_secretsmanager():
        # 重置单例实例,确保使用mock环境创建新客户端
        SecretsManagerClient._instance = None
        client = boto3.client("secretsmanager")
        client.create_secret(Name="my_key", SecretString="abcde")
        yield client

方法3:依赖注入模式

将客户端作为可选参数传入函数,Lambda环境下使用全局复用的客户端,测试时则传入mock的客户端。这种方式兼顾了Lambda暖启动的复用需求和测试的灵活性。

修改后的函数代码:

import boto3

# Lambda环境下复用的全局客户端
SM_CLIENT = boto3.client(service_name="secretsmanager")

def get_secret_key_string(sm_client=None):
    # 优先使用传入的客户端,未传入则用全局客户端
    client = sm_client or SM_CLIENT
    return client.get_secret_value(SecretId="my_key")["SecretString"]

修改后的测试代码:

from my_module import get_secret_key_string

def test_get_secret_key_string(secrets_client):
    # 测试时传入mock的客户端
    secret_string = get_secret_key_string(sm_client=secrets_client)
    assert secret_string == "abcde"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 09:40:27