I'm trying to test my helper methods that are wrappers around the existing boto3 dynamodb calls. When I try to test my helper method, I get the following error
botocore.errorfactory.ResourceNotFoundException: An error occurred (ResourceNotFoundException) when calling the Scan operation: Requested resource not found
The class that has the helper methods inherits from a class called Dynamodb that sets up the connection. Here is dynamodb_layer.py that has the main code that is being tested.
dynamodb_layer.py
class DynamoDB:
"""DynamoDB Initialization Class"""
@ExceptionDecorator
def __init__(self, table_name, partition_key):
self.connection = boto3.resource('dynamodb')
self.partition_key = partition_key
self.table = self.connection.Table(table_name)
class UsagePlan(DynamoDB):
"""Helper Class for fetching parameters from the DynamoDB Usage table"""
table_name = 'Usage'
@ExceptionDecorator
def __init__(self, partition_key=None):
super().__init__(table_name=self.table_name, partition_key=partition_key)
@ExceptionDecorator
def get_plans_from_dynamodb(self):
"""Get all usage plans"""
return json.loads(json.dumps(self.table.scan(), default=convert_decimal))
Here is my test file
test_dynamodb_layer.py
from dynamodb_layer.dynamodb_layer import UsagePlan
@pytest.fixture(autouse=True)
def dynamodb_instance():
yield UsagePlan('usage_plan_id')
@pytest.fixture
def aws_credentials():
"""Mocked AWS Credentials for moto."""
os.environ["AWS_ACCESS_KEY_ID"] = "testing"
os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
os.environ["AWS_SECURITY_TOKEN"] = "testing"
os.environ["AWS_SESSION_TOKEN"] = "testing"
def table_name():
return 'SwuTemp'
def s1_details():
return {'api_keys': [{'api_key': 'abcdefghijk987654321', 'api_key_id': '1newosh86', 'api_key_name': 'Quota Test'}, {'api_key': '53HGyaDTej57777nxnyE9KoGMnfl8tW21dPmRuPh6', 'api_key_id': 'wyengereu0j', 'api_key_name': 'mytestapi'}], 'usage_plan_id': 'jvpoe7', 'last_updated_date': '2021-09-07T20:07:35.695015', 'quota': {'limit': 150, 'offset': 0, 'period': 'MONTH'}, 'recently_updated': True, 'used_quota': {'wyengereu0j': [[0, 150], [0, 150], [0, 150], [0, 150], [5, 0], [0, 0], [0, 0]], '1newosh86': [[31, 9], [0, 9], [0, 9], [0, 9], [0, 9], [0, 9], [0, 9]]}, 'throttle': {'burstLimit': 3, 'rateLimit': 2}, 'stages': [{'name': 'myapitest', 'throttle': {'/camps/{id}/POST': {'burstLimit': 2, 'rateLimit': '1.0'}}, 'stage': 'Prod', 'apiId': 'qjia099d0'}], 'description': 'This is my description', 'name': 'Quota Test Usage plan'}
def create_table(init, table_name):
table = init.create_table(
TableName=table_name,
KeySchema=[
{
'AttributeName': 'usage_plan_id',
'KeyType': 'HASH' # Partition key
}
],
AttributeDefinitions=[
{
'AttributeName': 'usage_plan_id',
'AttributeType': 'S'
}
]
)
return table
def put_item( init, usage_plan_dict):
return init.put_item(Item={'usage_plan_id': usage_plan_dict['usage_plan_id'],
'api_keys': usage_plan_dict['api_keys'],
'description': usage_plan_dict['description'],
'last_updated_date': usage_plan_dict['last_updated_date'],
'name': usage_plan_dict['name'],
'quota': usage_plan_dict['quota'],
'recently_updated': usage_plan_dict['recently_updated'],
'stages': usage_plan_dict['stages'],
'throttle': usage_plan_dict['throttle'],
'used_quota': usage_plan_dict['used_quota']
})
@pytest.fixture
def dynamodb_client(aws_credentials):
"""Mock and initialize connection"""
with mock_dynamodb2():
boto3.setup_default_session()
client = boto3.resource('dynamodb')
table = create_table(client, table_name())
for plan in [s1_details(), s2_details()]:
put_item(table, plan)
yield table
def test_get_plans_from_dynamodb(dynamodb_client, dynamodb_instance):
response = dynamodb_instance.get_plans_from_dynamodb()
print(response)
When I run the above using pytest, I get the following reported on on the call to get_plans_from_dynamodb(). root:dynamodb_layer.py:51 An error occurred (ResourceNotFoundException) when calling the Scan operation: Requested resource not found .
.
It's almost as if the mock_dynamodb2 is not propagating to the get_plans_from_dynamodb() and instead it's using the inherited connection from the DynamoDB class rather than the mock connection that is supposed to get passed in.
Appreciate any pointers and tips to get around this. Thanks!