Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

aws boto3 unittest function that invokes a Lambda function

I have a python function that invokes an AWS Lambda function.

#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)
    )

How can I create a Unit Test for this function? I have been using Moto for other AWS services, but haven't been able to make it work for Lambda.

My attempt at using 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)

This errors out with:

botocore.exceptions.ClientError: An error occurred (404) when calling the Invoke operation: 
like image 894
mallocator4 Avatar asked Dec 07 '25 07:12

mallocator4


1 Answers

The boto3-client in lambda.py is initialized before any of the mocking takes place. As that client doesn't know it's being mocked, it probably tries to talk to AWS itself.

For you particular test case, there are a few solutions:

  • Place import lambda in the test itself, so that the boto3-client is created after the decorators have initialized
  • Override the client with the mocked version: lambda.client = conn
  • Pass the mocked client as an argument to lambda.invoke_function(conn, sample_input)
like image 150
Bert Blommers Avatar answered Dec 08 '25 22:12

Bert Blommers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!