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

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

关键修改说明

  1. 改用上下文管理器+yield:用with mock_dynamodb()包裹fixture逻辑,配合yield返回table,确保mock的生命周期覆盖整个测试用例的执行过程。
  2. 补全表创建参数:添加KeyType和ProvisionedThroughput参数,保证表能被mock环境正确创建。
  3. 移除不必要的参数:原fixture中的self和mocker参数如果未被使用,可以直接移除,简化代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:00:12