📜  如何模拟 AWS DynamoDB 服务以进行单元测试?

📅  最后修改于: 2022-05-13 01:57:09.804000             🧑  作者: Mango

如何模拟 AWS DynamoDB 服务以进行单元测试?

在本文中,我们将通过简短的示例了解如何模拟 DynamoDB 资源。但在此之前,首先,我们必须弄清楚为什么我们使用模拟来进行测试?模拟是我们尝试复制或复制测试所需的某些资源的东西。听起来很混乱吧?简单来说,我们制作了一些东西的副本,这样我们就可以测试任何东西的每一个方面,而不必担心丢失或更新重要的东西。

假设我们有一个将给定数据写入给定 DynamoDB 表的函数,如下所示。这是我们可以用来说明模拟 AWS DynamoDB 工作的最简单方法。在给定的函数中,它使用 DynamoDB 资源来存储数据。因此,在这里我们将在 Moto Python模块的帮助下模拟 AWS DynamoDB。 Moto 实现起来非常简单方便。

Python3
# store.py
  
def write(data, table_name):
   dynamodb = boto3.resource('dynamodb')
   table = dynamodb.Table(table_name)
   with table.batch_writer() as batch:
       batch.put_item(Item=data)


Python3
import boto3
from moto import mock_dynamodb2
import store
   
@mock_dynamodb2
def test_write_into_table():
   "Test the write_into_table with a valid input data"


Python3
table_name = 'test'
table = dynamodb.create_table(TableName=table_name,
       KeySchema=[{'AttributeName': 'date','KeyType': 'HASH'}],
       AttributeDefinitions=[{'AttributeName': 'date','AttributeType': 'S'}])


Python3
"""
Example of using moto to mock out DynamoDB table
"""
  
import boto3
from moto import mock_dynamodb2
import store
  
  
@mock_dynamodb2
def test_write_into_table():
    "Test the write_into_table with a valid input data"
    dynamodb = boto3.resource('dynamodb')
    table_name = 'test'
    table = dynamodb.create_table(TableName = table_name,
                                  KeySchema = [
                                  {'AttributeName': 'date', 'KeyType': 'HASH'}],
                                  AttributeDefinitions = [
                                  {'AttributeName': 'date', 'AttributeType': 'S'}])
    data = {'date': '06-Nov-2020',
            'organization': 'GeeksforGeeks', 'articles': 123456}
    store.write(data, table_name)
    response = table.get_item(Key={'date': data['date']})
    actual_output = response['Item']
    assert actual_output == data


为了模拟这个函数,我们将使用如下几个步骤——

  • 首先,通过导入必要的模块并用@mock_dynamodb2 装饰我们的测试方法来构建骨架。创建一个名为test_write_into_table.py的新文件并添加以下行:

Python3

import boto3
from moto import mock_dynamodb2
import store
   
@mock_dynamodb2
def test_write_into_table():
   "Test the write_into_table with a valid input data"

  • 现在,在test_write_into_table()方法中,创建一个 DynamoDB 资源,如下所示:
dynamodb = boto3.resource('dynamodb')
  • 让我们使用 DynamoDB 资源创建一个 DynamoDB 表,如下所示。在那里,我们创建了一个名为“test”的表,其主键为“date”,类型为字符串(“S”)。

Python3

table_name = 'test'
table = dynamodb.create_table(TableName=table_name,
       KeySchema=[{'AttributeName': 'date','KeyType': 'HASH'}],
       AttributeDefinitions=[{'AttributeName': 'date','AttributeType': 'S'}])

  • 在这里,我们将创建输入数据到 store.write(),它也将作为读取后的预期数据。
data = {'date' : '06-Nov-2020','organization' : 'GeeksforGeeks','articles' : 123456}
  • 为了更好地理解,我们采用了单个数据,但可以根据需要拥有更多数据。将上述数据写入表格后,表格将如下所示——
               date            organization          articles
          06-Nov-2020                    GeeksforGeeks                    123456          
  • 此时,store.write() 执行时,应该将给定的输入数据存储到对应的给定表中。
store.write(data,table_name)
  • 让我们通过传递“日期”作为主键来读取数据。请注意,我们正在获取一个带有几个键的字典,因此为了获取我们的数据,我们必须获取“Item”键的值。
response = table.get_item(Key={'date':data['date']})
actual_output = response['Item']
  • 让我们断言数据的主体与我们存储的相同。
assert actual_output == data

完整的源代码:

Python3

"""
Example of using moto to mock out DynamoDB table
"""
  
import boto3
from moto import mock_dynamodb2
import store
  
  
@mock_dynamodb2
def test_write_into_table():
    "Test the write_into_table with a valid input data"
    dynamodb = boto3.resource('dynamodb')
    table_name = 'test'
    table = dynamodb.create_table(TableName = table_name,
                                  KeySchema = [
                                  {'AttributeName': 'date', 'KeyType': 'HASH'}],
                                  AttributeDefinitions = [
                                  {'AttributeName': 'date', 'AttributeType': 'S'}])
    data = {'date': '06-Nov-2020',
            'organization': 'GeeksforGeeks', 'articles': 123456}
    store.write(data, table_name)
    response = table.get_item(Key={'date': data['date']})
    actual_output = response['Item']
    assert actual_output == data

输出 :

单元测试 DynamoDB