【问题标题】:How to emulate locally aws context for testing如何模拟本地 aws 上下文进行测试
【发布时间】:2021-04-12 16:03:44
【问题描述】:

我创建了一个 lambda 我根据context.invoked_function_arn检索区域。

所以,我想使用测试脚本文件而不是通过 conftest.py 创建和模拟这种行为,因为我在同一个测试脚本中实现了其他单元测试方法。

我发现这个链接lambda-context 很有用,并且在我的测试脚本中实现了相同的概念。然而,我一直收到 AttributeError: 'function' object has no attribute 'invoked_function_arn' 错误消息。

@pytest.fixture
def mock_lambda_context():
    class ClientContext:
        """
        Class for mocking Context

        Has `custom`, `env`, and `client` `__slots__`
        """

        __slots__ = ["custom", "env", "client"]

    def make_obj_from_dict(_class, _dict, fields=None):
        """
        Makes an object of `_class` from a `dict`

        :param _class: A class representing the context
        :type _class: `ContextClass`
        :param _dict: A dictionary of data
        :type _dict: `dict`
        :param fields: [description], defaults to None
        :type fields: [type], optional
        :return: An object
        :rtype: `ClientContext` class
        """
        if _dict is None:
            return None
        obj = _class()
        set_obj_from_dict(obj, _dict)
        return obj

    def set_obj_from_dict(obj, _dict, fields=None):
        if fields is None:
            fields = obj.__class__.__slots__
        for field in fields:
            setattr(obj, field, _dict.get(field, None))

    class LambdaContext(object):
        """
        Create a Lambda Context Class object
        """

        def __init__(self, invokeid, client_context, invoked_function_arn=None):
            self.aws_request_id = invokeid
            self.log_group_name = "AWS_LAMBDA_LOG_GROUP_NAME"
            self.log_stream_name = "AWS_LAMBDA_LOG_STREAM_NAME"
            self.function_name = "AWS_LAMBDA_FUNCTION_NAME"
            self.memory_limit_in_mb = "AWS_LAMBDA_FUNCTION_MEMORY_SIZE"
            self.function_version = "AWS_LAMBDA_FUNCTION_VERSION"
            self.invoked_function_arn = "arn:aws:lambda:eu-west-1:123456789012:function:" \
                                        "ExampleLambdaFunctionResourceName-AULC3LB8Q02F"

            self.client_context = make_obj_from_dict(ClientContext, client_context)
            if self.client_context is not None:
                self.client_context.client = None
            self.identity = None

        def get_remaining_time_in_millis(self):
            return None

        def log(self, msg):
            str_msg = str(msg)
            print(str_msg)

    context = LambdaContext("AWS_ID", {})

    return context

def test_handler(events, mock_lambda_context):
    res = handler(events, mock_lambda_context)
    assert res['context.invoked_function_arn'] == "arn:aws:lambda:eu-west-1:123456789012:function:ExampleLambdaFunctionResourceName-AULC3LB8Q02F" 

谁能指点我如何解决这个愚蠢的问题?

【问题讨论】:

  • 我想出了一些替代方法,但如果有人对这种方法有任何 cmets,请告诉我。同时,我将发布我的替代方式作为问题的答案。

标签: python amazon-web-services lambda pytest


【解决方案1】:

我像这样创建了一个 sample_context.json:

{
    "invoked_function_arn": "arn:aws:lambda:eu-west-1:123456789012:function:ExampleLambdaFunctionResourceName-AULC3LB8Q02F",
    "log_group_name": "/aws/lambda/ExampleLambdaFunctionResourceName-AULC3LB8Q02F",
    "function_name": "ExampleLambdaFunctionResourceName-AULC3LB8Q02F",
    "function_version": "$LATEST"
}

然后在我的主测试文件中:

    @pytest.fixture
    def context_outcome():
        return load_json_from_file('sample_context.json')
    
    
    @pytest.fixture
    def context(context_outcome):
        response = type('new', (object,), context_outcome)
        seqs = tuple, list, set, frozenset
        for i, j in context_outcome.items():
            if isinstance(j, dict):
                setattr(response, i, context(j))
            elif isinstance(j, seqs):
                setattr(response, i,
                        type(j)(context(sj) if isinstance(sj, dict) else sj for sj in j))
            else:
                setattr(response, i, j)
        return response

def test_main(events, context):
    assert context.invoked_function_arn == "arn:aws:lambda:eu-west-1:123456789012:function:ExampleLambdaFunctionResourceName-AULC3LB8Q02F"

【讨论】:

  • 救了我.....小时 - 很惊讶这在任何地方都没有记录(除非我的谷歌技能失败)。 C# 有一个库 (Amazon.Lambda.TestUtilities),它有一个 TestContext...
猜你喜欢
  • 1970-01-01
  • 2011-05-15
  • 2013-08-18
  • 2023-03-18
  • 2013-04-29
  • 2021-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多