3

我有一个调用 AWS Lambda 函数的 python 函数。

#lambda.py
import boto3
import os

client    = boto3.client('lambda')
MY_LAMBDA = os.environ['MY_LAMBDA']

def invoke_function(input):
    response = client.invoke(
        FunctionName=MY_LAMBDA,
        InvocationType='RequestResponse',
        Payload=json.dumps(input)
    )

如何为此功能创建单元测试?我一直在将 Moto 用于其他 AWS 服务,但无法使其适用于 Lambda。

我尝试使用moto:

#test_lambda.py

from unittest.mock import MagicMock, patch
from unittest.mock import ANY
from moto import mock_lambda
import boto3
import os
import zipfile
import io
import lambda

class LambdaTest(unittest.TestCase):

    def get_test_zip_file(self):
        pfunc = '''
                def lambda_handler(event, context):
                    return event
                '''
        zip_output = io.BytesIO()
        zip_file = zipfile.ZipFile(zip_output, 'w', zipfile.ZIP_DEFLATED)
        zip_file.writestr('lambda_function.py', pfunc)
        zip_file.close()
        zip_output.seek(0)
        return zip_output.read()

    @mock_lambda
    def test_invoke_requestresponse_function(self):
        conn = boto3.client('lambda', 'us-east-1')
        conn.create_function(
            FunctionName='test-func',
            Runtime='python3.8',
            Role='test-iam-role',
            Handler='lambda_function.lambda_handler',
            Code={
                'ZipFile': self.get_test_zip_file(),
            },
            Description='test lambda function',
            Timeout=3,
            MemorySize=128,
            Publish=True
        )

        sample_input = {'msg': 'Test Input'}

        result = lambda.invoke_function(sample_input)

这会出错:

botocore.exceptions.ClientError: An error occurred (404) when calling the Invoke operation: 
4

1 回答 1

2

lambda.py 中的 boto3-client 在任何模拟发生之前被初始化。由于该客户端不知道它正在被嘲笑,它可能会尝试与 AWS 本身对话。

对于您的特定测试用例,有一些解决方案:

  • 放入import lambda测试本身,以便在装饰器初始化后创建 boto3-client
  • 使用模拟版本覆盖客户端:lambda.client = conn
  • 将模拟的客户端作为参数传递给 lambda.invoke_function(conn, sample_input)
于 2020-04-17T08:48:43.657 回答