如何模拟 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
输出 :