Pytest Fixture中Mock DynamoDB失败,PutItem提示资源未找到
解决pytest fixture中使用mock_dynamodb导致的ResourceNotFoundException问题
问题根源
你的代码存在两个核心问题:
- mock生命周期不匹配:
@mock_dynamodb装饰器直接作用在fixture上时,仅在fixture函数执行期间生效。当fixture返回table对象给测试用例后,mock上下文已关闭,测试用例调用table方法时处于未mock的环境,无法找到之前创建的表。 - 表创建参数不全:调用
create_table时缺少两个必填参数,导致表未被正确创建:KeySchema中的每个元素必须指定KeyType(如HASH表示分区键)- 必须提供
ProvisionedThroughput配置项(即使是mock环境,moto也要求该参数)
修正后的代码
Fixture代码
import boto3 import pytest from moto import mock_dynamodb @pytest.fixture def create_test_table(): with mock_dynamodb(): table_name = "table" dynamodb = boto3.resource("dynamodb") table = dynamodb.create_table( TableName=table_name, KeySchema=[ {"AttributeName": "name", "KeyType": "HASH"}, ], AttributeDefinitions=[ {"AttributeName": "name", "AttributeType": "S"}, ], ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 1} ) # 确保表初始化完成(mock环境中可省略,但添加后更贴近真实场景) table.wait_until_exists() yield table
测试用例代码
def test_get_item_from_table_found(create_test_table): table = create_test_table item = {"name": "name"} table.put_item(Item=item) # 后续测试逻辑,比如查询并验证结果 response = table.get_item(Key={"name": "name"}) assert response["Item"] == item
关键修改说明
- 改用上下文管理器+yield:用
with mock_dynamodb()包裹fixture逻辑,配合yield返回table,确保mock的生命周期覆盖整个测试用例的执行过程。 - 补全表创建参数:添加
KeyType和ProvisionedThroughput参数,保证表能被mock环境正确创建。 - 移除不必要的参数:原fixture中的
self和mocker参数如果未被使用,可以直接移除,简化代码。
内容的提问来源于stack exchange,提问作者SafeDev
相关产品推荐
相关产品推荐

