Home > Back-end >  How to mock an AWS Lambda with moto
How to mock an AWS Lambda with moto

Time:11-07

I created a code to invoke a AWS lambda function created somewhere else.

I would like to use moto for testing it, but I don't really understand how to do it and I continue to obtain errors.

This is a simple example of the main code:

import boto3
import json


class SimpleLambda:
    def __init__(self):
        self.aws_lambda = boto3.client("lambda", region_name="eu-west-2")

    def __call__(self):
        try:
            lambda_response = self.aws_lambda.invoke(
                FunctionName="test-lambda",
                Payload=json.dumps(
                    {
                        "Records": [
                            {
                                "Source": "test_source",
                                "Version": "test_version",
                            }
                        ]
                    }
                ),
            )
            return lambda_response["Payload"].read()
        except Exception as err:
            print(f"Could not invoke simple lambda: {err}")
            return None

and the test:

import os
import pytest
import unittest.mock as mock

import boto3
from moto import mock_lambda

from aws_lambda import SimpleLambda


@pytest.fixture
def aws_credentials():
    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"


@pytest.fixture
def lambda_client(aws_credentials):
    with mock_lambda():
        yield boto3.client("lambda", region_name="eu-west-2")


@pytest.fixture
def lambda_test(lambda_client):
    lambda_client.create_function(
        FunctionName="test-lambda",
        Role="arn:aws:iam::123456789012:role/doesnotexist",
        Code={"ZipFile": b"test"}
    )
    yield


def test_simple_lambda_call(lambda_client, lambda_test):
    simple_lambda = SimpleLambda()

    test = simple_lambda()

I obtain the error:

botocore.errorfactory.InvalidParameterValueException: An error occurred (InvalidParameterValueException) when calling the CreateFunction operation: The role defined for the function cannot be assumed by Lambda.

I found several example about how to use moto with S3 bucket, but nothing with lambda.

Running the code in this other question, I obtain the same error.

Any advice?

CodePudding user response:

Moto also validates whether the IAM role exists, just like AWS does.

So make sure that the IAM role is created first:

with mock_iam():
    iam = boto3.client("iam", region_name="eu-west-2")
    iam_role = iam.create_role(
        RoleName="my-role",
        AssumeRolePolicyDocument="some policy",
        Path="/my-path/",
    )["Role"]["Arn"]
  • Related