0

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!"
        })
bSr
  • 1,410
  • 3
  • 16
  • 30

0 Answers0