You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为AWS Python Lambda函数编写单元测试(Mock使用疑问)

问题描述

我有一个位于handler.py中的Python Lambda函数,代码如下:

def isolate_endpoints(event=None, context=None):

    endpoint_id = event['event']['endpoint_id']

    client = get_edr_client()
    response = client.isolate_endpoints(endpoint_id=endpoint_id)

    return response # E.g {"reply":{"status":"success", "error_msg":null}}

utils.py中get_edr_client的定义和实现如下:

from EDRAPI import EDRClient
def get_edr_client():
    return EDRClient(api_key="API_KEY")

我希望为该Lambda编写单元测试,但对Mock、MagicMock的实际实现不太理解,当前我的单元测试写在test_calls中,代码如下:

@mock.patch('project_module.utils.get_edr_client')
def test_isolate_endpoints(get_edr_client: MagicMock):
    client = MagicMock()
    get_edr_client.return_value = client
    mock_event = {"event": {"endpoint_id":"foo"}}
    resp = isolate_endpoints(event=mock_event) # 在此直接调用Lambda是否正确?
    assert resp is not None
    expected = [call()] ## 这是什么?# 此处应如何编写?

    assert client.isolate_endpoints.call_args_list == expected

我的疑问:

  • 是否可直接在测试中调用Lambda函数?
  • expected的call()如何正确编写?
  • 如何用Mock完成该单元测试?

解决方案

1. 能否直接调用Lambda函数?

完全可以。Lambda函数本质就是普通的Python函数,直接调用它是单元测试的标准做法——不需要启动Lambda运行时,只要传入模拟的event和context参数(你的函数没用到context,传None即可),就能测试函数逻辑。

2. 如何正确编写expected的call()?

call()是unittest.mock提供的工具,用来模拟函数调用的参数签名。你的client.isolate_endpoints被调用时传入了endpoint_id="foo",对应的call需要带上这个关键字参数:

from unittest.mock import call

expected = [call(endpoint_id="foo")]

call_args_list会记录Mock对象的所有调用参数,用这个expected列表断言,就能验证isolate_endpoints方法是否被传入了正确的参数。

3. 完整的Mock单元测试实现

需要注意几个核心点:

  • 正确patch依赖的路径:要用@mock.patch('handler.get_edr_client')——因为handler.py中导入并使用了get_edr_client,所以要patchhandler模块里的这个引用,而非utils里的原函数(这是Mock的常见坑点)。
  • 给Mock的isolate_endpoints方法设置返回值,模拟EDR客户端的响应,验证Lambda函数是否正确返回该响应。

完整测试代码如下:

from unittest.mock import patch, MagicMock, call
from handler import isolate_endpoints

@patch('handler.get_edr_client')
def test_isolate_endpoints(get_edr_client_mock: MagicMock):
    # 1. 模拟EDR客户端及其返回值
    mock_edr_client = MagicMock()
    mock_response = {"reply":{"status":"success", "error_msg":None}}
    mock_edr_client.isolate_endpoints.return_value = mock_response
    get_edr_client_mock.return_value = mock_edr_client

    # 2. 构造测试用的event
    test_event = {"event": {"endpoint_id": "foo"}}

    # 3. 调用Lambda函数
    result = isolate_endpoints(event=test_event)

    # 4. 断言验证
    # 验证get_edr_client被调用了一次
    get_edr_client_mock.assert_called_once()
    # 验证isolate_endpoints方法被传入了正确的endpoint_id
    mock_edr_client.isolate_endpoints.assert_called_once_with(endpoint_id="foo")
    # 验证Lambda函数返回了正确的响应
    assert result == mock_response

补充说明

  • assert_called_once()和assert_called_once_with()是比直接对比call_args_list更简洁的断言方法,推荐使用。
  • 如果要模拟异常场景(比如EDR客户端调用失败),可以给mock_edr_client.isolate_endpoints.side_effect设置一个异常,再断言Lambda函数的错误处理逻辑(如果有)。

内容的提问来源于stack exchange,提问作者rustam Shirinov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:39:51