Python测试调用DynamoDB的Lambda:Mock问题及无Moto测试方案
问题解决:Mock Boto3 Client 验证 DynamoDB put_item 调用
核心原因
直接用 mock_client.put_item.call_count 得到0,是因为 @mock.patch("boto3.client") 替换的是boto3.client这个构造函数,而非它返回的DynamoDB客户端实例。put_item 是客户端实例的方法,不是构造函数的方法,必须访问构造函数返回的mock实例才能检查调用记录。
解决步骤与测试示例
1. 正确获取客户端实例的Mock对象
通过 mock_client.return_value 访问boto3.client()返回的mock实例,所有对DynamoDB客户端的方法调用都会记录在这里。
2. 验证put_item调用次数与参数
以下是完整的测试代码示例(替换成你的Lambda模块名和实际参数):
from unittest import mock import your_lambda_file # 替换成你的Lambda函数所在的模块 def test_dynamodb_put_item(): # Patch boto3.client with mock.patch("boto3.client") as mock_client: # 构造测试用的event和context test_event = {} test_context = mock.Mock() # 执行Lambda handler your_lambda_file.handler(test_event, test_context) # 验证DynamoDB客户端是否被正确初始化 mock_client.assert_called_once_with("dynamodb") # 获取客户端实例的Mock dynamodb_client_mock = mock_client.return_value # 验证put_item被调用了1次 assert dynamodb_client_mock.put_item.call_count == 1 # 验证存入的条目参数是否符合预期(替换成你的实际参数) expected_params = { "TableName": "YourTargetTable", "Item": { "user_id": {"S": "user_123"}, "content": {"S": "test_content"} # 其他你要存入的属性 } } # 断言put_item被传入了正确的参数 dynamodb_client_mock.put_item.assert_called_once_with(**expected_params)
关键说明
mock_client是被patch的构造函数,它的return_value才是handler里dynamodb = boto3.client('dynamodb')得到的客户端实例。- 使用
assert_called_once_with可以精准验证put_item的入参,确保存入的条目完全符合预期,这就是不使用Moto时验证数据存入正确性的核心方式。
内容的提问来源于stack exchange,提问作者user20519169
相关产品推荐
相关产品推荐

