簡體   English   中英

Mocking 與 moto 的 lambda 響應

[英]Mocking a lambda response with moto

在我的代碼中的某處,調用 lambda 以返回真/假響應。 我試圖在我的單元測試中模擬這個 lambda 但沒有成功。

這是我的代碼:

def _test_update_allowed():
    old = ...
    new = ...
    assert(is_update_allowed(old, new) == True)

在內部, is_update_allowed調用 lambda,這是我要模擬的。

我嘗試在測試上方添加以下代碼:

import zipfile
import io
import boto3
import os

@pytest.fixture(scope='function')
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'


CLIENT = boto3.client('lambda', region_name='us-east-1')

# Expected response setup and zip file for lambda mock creation
def lambda_event():
    code = '''
        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', code)
    zip_file.close()
    zip_output.seek(0)
    return zip_output.read()

# create mocked lambda with zip file
def mock_some_lambda(lambda_name, return_event):
    return CLIENT.create_function(
        FunctionName=lambda_name,
        Runtime='python2.7',
        Role='arn:aws:iam::123456789:role/does-not-exist',
        Handler='lambda_function.lambda_handler',
        Code={
            'ZipFile': return_event,
        },
        Publish=True,
        Timeout=30,
        MemorySize=128
    )

然后將我的測試更新為:

@mock_lambda
def _test_update_allowed():
    mock_some_lambda('hello-world-lambda', lambda_event())
    old = ...
    new = ...
    assert(is_update_allowed(old, new) == True)

但我收到以下錯誤,這讓我認為它實際上是在嘗試與 AWS 對話

botocore.exceptions.ClientError: An error occurred (UnrecognizedClientException) when calling the CreateFunction operation: The security token included in the request is invalid.

從錯誤消息中,我可以確認這絕對不是 AWS 問題。 它清楚地表明它正在嘗試使用一些無效的憑據。 所以這歸結為代碼。

我假設您已經有必要庫的導入語句,因為這些在共享代碼中也不可見

import pytest
import moto

from mock import mock, patch
from moto import mock_lambda

所以你需要使用

def aws_credentials():
 .....

在創建客戶端時,因為從代碼中我看不到您使用的是相同的。

@pytest.fixture(scope='function')
def lambda_mock(aws_credentials):
with mock_lambda():
    yield boto3.client('lambda', region_name='us-east-1')

最終你的模擬

@pytest.fixture(scope='function')
def mock_some_lambda(lambda_mock):
    lambda_mock.create_function(
        FunctionName=lambda_name,
        Runtime='python2.7',
        Role='arn:aws:iam::123456789:role/does-not-exist',
        Handler='lambda_function.lambda_handler',
        Code={
            'ZipFile': return_event,
        },
        Publish=True,
        Timeout=30,
        MemorySize=128
    )
 yield

然后測試 function

    def _test_update_allowed(lambda_mock,mock_some_lambda):
        lambda_mock.invoke(...)
          .....

不能給出一個可行的例子,因為不確定完整的邏輯是什么。 看看這個帖子之間。

這些問題似乎是由於不存在的 arn 角色造成的。 嘗試 mocking 就像在 moto 庫測試中一樣

def get_role_name():
    with mock_iam():
        iam = boto3.client("iam", region_name=_lambda_region)
        try:
            return iam.get_role(RoleName="my-role")["Role"]["Arn"]
        except ClientError:
            return iam.create_role(
                RoleName="my-role",
                AssumeRolePolicyDocument="some policy",
                Path="/my-path/",
            )["Role"]["Arn"]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM