boto / botocore

The low-level, core functionality of boto3 and the AWS CLI.
Apache License 2.0
1.44k stars 1.06k forks source link

Stubber.add_response for query method validate against an invalid schema #3199

Closed TiphaineLAURENT closed 1 week ago

TiphaineLAURENT commented 2 weeks ago

Describe the bug

Stubber.add_response for query method validate against an invalid schema

Expected Behavior

To be able to mock the query method with a return value

Current Behavior

Stubber.validate_parameters raises a botocore.exceptions.ParamValidationError: Parameter validation failed with dict as the only valid type

Reproduction Steps

import boto3
from botocore.stub import Stubber

dynamodb_resource = boto3.resource("dynamodb")
dynamodb_stubber = Stubber(dynamodb_resource)

dynamodb_stubber.add_response("query", {"Items": [{"DocumentId": document_id, "DocumentVersion": document_version.timestamp(), "RawDocumentS3Uri": document_raw_s3_uri}]})
...
E           botocore.exceptions.ParamValidationError: Parameter validation failed:
E           Invalid type for parameter Items[0].DocumentId, value: 8048ccd9-3b7e-4bb1-a6e9-ada69204a299, type: <class 'str'>, valid types: <class 'dict'>
E           Invalid type for parameter Items[0].DocumentVersion, value: 1298093434.865334, type: <class 'float'>, valid types: <class 'dict'>
E           Invalid type for parameter Items[0].RawDocumentS3Uri, value: http://www.saunders.com/app/list/appcategory.php, type: <class 'str'>, valid types: <class 'dict'>

Possible Solution

No response

Additional Information/Context

The actual code tested a real dynamodb service works perfectly fine.

The expected schema from Stubber does not match the documentation https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/table/query.html

SDK version used

botocore 1.34.108

Environment details (OS name and version, etc.)

Python3.12.3

tim-finnigan commented 2 weeks ago

Thanks for reaching out. It looks like there are issues with how you are using the Stubber class. Here is the documentation for reference: https://botocore.amazonaws.com/v1/documentation/api/latest/reference/stubber.html. I think example below addresses what you're trying to do:

import boto3
from botocore.stub import Stubber

# Set up the test data
document_id = "8048ccd9-3b7e-4bb1-a6e9-ada69204a299"
document_version = 1298093434.865334
document_raw_s3_uri = "http://www.saunders.com/app/list/appcategory.php"

# Create a DynamoDB resource
dynamodb_resource = boto3.resource("dynamodb")

# Create a DynamoDB Stubber
dynamodb_stubber = Stubber(dynamodb_resource.meta.client)

# Set up the expected response for the query command
expected_params = {
    "TableName": "stubber-test",
    "KeyConditionExpression": "partition_key = :partition_key",
    "ExpressionAttributeValues": {
        ":partition_key": {"S": "my-partition-key-value"}
    }
}

response = {
    "Items": [
        {
            "DocumentId": {"S": document_id},
            "DocumentVersion": {"N": str(document_version)},
            "RawDocumentS3Uri": {"S": document_raw_s3_uri}
        }
    ],
    "Count": 1,
    "ScannedCount": 1,
    "LastEvaluatedKey": {
        "DocumentId": {"S": document_id}
    }
}

# Add the expected response to the Stubber
dynamodb_stubber.add_response("query", response, expected_params)

# Activate the Stubber
with dynamodb_stubber:
    # Call the query command
    result = dynamodb_resource.Table("stubber-test").query(
        KeyConditionExpression="partition_key = :partition_key",
        ExpressionAttributeValues={
            ':partition_key': {'S': 'my-partition-key-value'}
        }
    )

    # Assert that the response matches the expected response
    assert result == response
TiphaineLAURENT commented 1 week ago

Oh I see. It seems I was missing the type in the response format ({"<type>": <value>}). Thank you very much it is very helpful

github-actions[bot] commented 1 week ago

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.