We are developing a Flask REST API using dynamoDB as a database. I want to write the unit test code for the same application. I am using moto to mock the dynamoDB. here is the code of conftest.py
import os
import boto3
import pytest
from moto import mock_dynamodb2
@pytest.fixture(scope='module')
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'
@pytest.yield_fixture(scope='module')
def dynamodb_resource(aws_credentials):
# DDB mock resource
with mock_dynamodb2():
conn = boto3.resource('dynamodb', region_name='ap-south-1')
yield conn
I am also able to insert, delete and create table inside this mock database.
create table:
@contextmanager
def ddb_setup(client_resource):
# create mock ddb bucket and object to be available to all methods in the test class
client_resource.create_table(
TableName=TableName,
KeySchema=[
{
'AttributeName': 'user_name',
'KeyType': 'HASH'
}, {
'AttributeName': 'last_name',
'KeyType': 'RANGE'
}
],
AttributeDefinitions=[
{
'AttributeName': 'user_name',
'AttributeType': 'S'
}, {
'AttributeName': 'last_name',
'AttributeType': 'S'
}
],
ProvisionedThroughput={
'ReadCapacityUnits': 5,
'WriteCapacityUnits': 5
}
)
yield
test for creating the table and inserting data to it (test_user.py)
class TestClassDDB:
def test_create_table(self, dynamodb_resource, dynamodb_client):
# test the successfulcreation of a table
with ddb_setup(dynamodb_resource):
try:
response = dynamodb_client.describe_table(TableName=TableName)
assert response['Table']['TableName'] == TableName
except ClientError as err:
assert err.response['Error']['Code'] == 'ResourceNotFoundException'
def test_put_object(self, dynamodb_resource):
# test the successful adding of an object to a table
table = dynamodb_resource.Table(TableName)
table.put_item(
Item={
'user_name': 'WillSmith',
'last_name': 'Smith',
'account_type': 'standard_user'
}
)
results = table.get_item(
Key={
'user_name': 'WillSmith',
'last_name': 'Smith'
}
)
assert results['Item']['user_name'] == 'WillSmith'
Above code is running without any error.
my question is, currently the flask application is using live dynamodb. In order to test the application I should use mock dynamodb, so how can I point this mock dynamodb to the flask application. here is the sample code for the flask application that I have written (app.py).
import os
import boto3
from flask import Flask, jsonify, request
app = Flask(__name__)
USERS_TABLE = os.environ['USERS_TABLE']
client = boto3.client('dynamodb')
@app.route("/getUsers/<string:user_id>")
def get_user(user_id):
try:
resp = client.get_item(
TableName=USERS_TABLE,
Key={
'userId': {'S': user_id}
}
)
item = resp.get('Item')
if not item:
return jsonify({'error': 'User does not exist'}), 404
if item.get('status').get('N') == '-1':
return jsonify({'error': 'user is not active'}), 404
return jsonify({
'userId': item.get('userId').get('S'),
'name': item.get('name').get('S'),
'message': True
})
except Exception as e:
print(e)
traceback.print_exc()
return jsonify({
"status": False,
"message": "some internal error occurred!"
})