Aws lambda 使用存根客户端覆盖boto3客户端

Aws lambda 使用存根客户端覆盖boto3客户端,aws-lambda,pytest,Aws Lambda,Pytest,有很多资源可以使用pytest、Moto和botocorestubber编写单元测试 编辑。经过进一步调查后,我将重新表述这个问题: 我有一个lambda_函数python脚本,我想用pytest和Boto-stuber测试它。在lambda_函数的内部我从另一个python文件导入一个ssm_客户端(ssm_clt=boto3.client('ssm',region_name=region)) 问题是当我像这样设置pytest时: def test_lambda_handler(ssm_stu

有很多资源可以使用pytest、Moto和botocorestubber编写单元测试

编辑。经过进一步调查后,我将重新表述这个问题:

我有一个
lambda_函数
python脚本,我想用pytest和Boto-stuber测试它。在
lambda_函数的内部
我从另一个python文件导入一个ssm_客户端(
ssm_clt=boto3.client('ssm',region_name=region)

问题是当我像这样设置pytest时:

def test_lambda_handler(ssm_stubber):
    ssm_stubber.activate()
    ssm_stubber.add_response(
        'get_parameters_by_path',
        expected_params={'Path': 'my/ssm/parameter', 'Recursive': 'True'},
        service_response={
            'Parameters': [
                {
                    'Name': 'my/ssm/parameter',
                    'Type': 'String',
                    'Value': 'my_string returned',
                },
            ],
        },
    )
    ssm_stubber.deactivate()

    ssm_stubber.assert_no_pending_responses()
ssm_stubber
定义为pytest夹具:

@pytest.fixture(autouse=True)
def ssm_stubber():
    with Stubber(clients.ssm_clt) as stubber:
        yield stubber
它使用的是实际的boto3客户端,而不是stubber客户端,因为我在
lambda_函数中有一个import语句。我正努力想办法克服这一切。我不想在常规的
lambda_函数
中放一堆只用于测试的代码

这几乎就像我需要一个有条件的导入,但据我所知,这是一个糟糕的做法


我是否以一种几乎不可能以这种方式将stubber与pytest结合使用的方式构建了我的项目?

因此我最终只使用了pytest的monkeypatch功能。这比尝试修补Boto3客户端并使其正确连接到存根要简单得多。下面是我所做的一些示例代码

这是我想要测试的函数。问题是来自
param\u dictionary=setup.get\u ssm\u parameters()
函数中的AWS API调用从未正确中断。这不是存根,因为它不在测试所测试的功能范围内。这导致它在测试期间尝试使用真实的boto3客户端调用。lambda_处理程序中的所有其他API调用始终被正确地存根

"""lambda_function.py"""
    import another_function

    # this was the function that has an SSM AWS client call in it that wasn't get properly stubbed because it is outside of the function I am testing but is still executed as part of the script    
    param_dictionary = another_function.get_ssm_parameters()

    def lambda_handler(event, context):
        # other code here that runs fine and AWS API calls that are properly stubbed
这是包含对参数存储的AWS API调用的文件

"""another_function.py"""
import boto3

ssm_clt = boto3.client('ssm', region_name='us-west-2')

def get_ssm_parameters()
    param_dict = {}
    ssm_resp = ssm_clt.get_parameters_by_path(
        Path=f'/{os.environ["teamName"]}/{os.environ["environment"]}/etl',
        Recursive=True
    )
    
    for parameter in ssm_resp["Parameters"]:
        param_dict.update(json.loads(parameter["Value"]))

    return param_dict 
这是我的测试。您可以看到我传入了money patch pytest.fixture,它将修补函数
get\u ssm\u parameters()
的响应,因此它不会进行API调用

"""test_lambda_function.py"""
def test_my_func_one(return_param_dict):
    from lambda_function import lambda_handler

    # insert other snubbers and "add_response" code here for AWS API calls that occur inside of the lambda_handler

    lambda_handler('my_event', None)
这是pytest的配置文件,我在其中设置了monkeypatching。我使用monkeypatch的
setattr
功能覆盖
get\u ssm\u parameters()
的返回。此返回在函数
param_dict()中定义

最终,这比尝试在我正在测试的函数之外的另一个模块中修补客户机要简单得多

"""conftest.py"""
import pytest
import another function
def param_dict():
    param_dict = {"my_key": "my_value"}

    return param_dict


@pytest.fixture(autouse=True)
def return_param_dict(monkeypatch):
    monkeypatch.setattr(another_function, "get_ssm_parameters", param_dict)