测试 Flask 应用程序时如何模拟 AWS 资源

How to mock out AWS resources when testing flask app

我有一个使用 dynamodb 等 AWS 服务的 Flask 应用程序。我想在单元测试期间模拟这些,但我在这样做时遇到了麻烦。

这是一个对我不起作用的最小示例:

from flask import Flask
import boto3

app = Flask(__name__)

@app.route("/")
def hello():
    aws_session = boto3.session.Session()
    dynamodb = aws_session.resource("dynamodb")
    table = dynamodb.Table("test-table")
    table.put_item(Item={
        "hello": "world"
    })
    return "ok"


from moto import mock_dynamodb
import pytest


@pytest.fixture
def client():
    with app.test_client() as client:
        yield client


@mock_dynamodb
def test_response(client):
    rv = client.get('/')
    assert rv.data == "ok"

我收到资源不存在的错误。这意味着实际上正在进行 AWS 调用。为什么调用没有被模拟出来?

Moto 更像是一个模拟器,而不是传统的模拟。它模拟了快乐路径,但如果输入有任何问题,它也会抛出与 AWS 相同的错误。

AWS 会在此处抛出错误,指出 table 不存在 - 所以 Moto 也会这样做。 (而且,与 AWS 一样,Moto 实际上需要 table 存在才能 'persist' 那里的项目。)

首先创建 table 时模拟请求成功:

@app.route("/")
def hello():
    aws_session = boto3.session.Session()
    conn = aws_session.client("dynamodb")
    conn.create_table(
        TableName="test-table",
        KeySchema=[{"AttributeName": "hello", "KeyType": "HASH"}],
        AttributeDefinitions=[{"AttributeName": "hello", "AttributeType": "S"}],
        ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
    )
    dynamodb = aws_session.resource("dynamodb")
    table = dynamodb.Table("test-table")
    table.put_item(Item={
        "hello": "world"
    })
    return "ok"