[英]How to mock failed operations with moto, @mock_dynamodb2?
我目前正在嘗試使用 Moto 和 @mock_dynamodb2 為我的 python 代碼編寫單元測試。 到目前為止,我一直在測試我的“成功操作”測試用例。 但是我很難讓它為我的“失敗案例”工作。
在我的測試代碼中,我有:
@mock_dynamodb2
class TestClassUnderTestExample(unittest.TestCase):
def setUp(self):
ddb = boto3.resource("dynamodb", "us-east-1")
self.table = ddb.create_table(<the table definition)
self.example_under_test = ClassUnderTestExample(ddb)
def test_some_thing_success(self):
expected_response = {<some value>}
assert expected_response = self.example_under_test.write_entry(<some value>)
def test_some_thing_success(self):
response = self.example_under_test.write_entry(<some value>)
# How to assert exception is thrown by forcing put item to fail?
TestClassUnderTestExample 看起來像這樣:
class ClassUnderTestExample:
def __init__(self, ddb_resource=None):
if not ddb_resource:
ddb_resource = boto3.resource('dynamodb')
self.table = ddb_resource.Table(.....)
def write_entry(some_value)
ddb_item = <do stuff with some_value to create sanitized item>
response = self.table.put_item(
Item=ddb_item
)
if pydash.get(response, "ResponseMetadata.HTTPStatusCode") != 200:
raise SomeCustomErrorType("Unexpected response from DynamoDB when attempting to PutItem")
return ddb_item
在實際模擬 .put_item 操作以返回非成功值時,我完全陷入困境,以便我可以測試 ClassUnderTestExample 是否會按預期處理它並拋出自定義錯誤。 我已經嘗試過在運行測試之前刪除表格之類的事情,但這只會在獲取表格時引發異常,而不是執行帶有錯誤代碼的 PutItem。
我還嘗試為 pydash 或測試上方的表格打上補丁,但我一定是做錯了什么。 我在 moto 的文檔中找不到任何內容。 任何幫助,將不勝感激!
Moto 的目標是完全模仿 AWS 的行為,包括當用戶提供錯誤輸入時的行為。 換句話說,對 AWS 的 put_item() 調用失敗,也會/應該對 Moto 失敗。
沒有內置方法可以強制對有效輸入進行錯誤響應。
從您的示例中很難看出如何強制執行此操作,但看起來值得嘗試使用此行來創建無效輸入:
ddb_item = <do stuff with some_value to create sanitized item>
是的你可以。 為此使用嘲笑。 簡單且可運行的示例:
from unittest import TestCase
from unittest.mock import Mock
from uuid import uuid4
import boto3
from moto import mock_dynamodb2
def create_user_table(table_name: str) -> dict:
return dict(
TableName=table_name,
KeySchema=[
{
'AttributeName': 'id',
'KeyType': 'HASH'
},
],
AttributeDefinitions=[
{
'AttributeName': 'id',
'AttributeType': 'S'
},
],
BillingMode='PAY_PER_REQUEST'
)
class UserRepository:
table_name = 'users'
def __init__(self, ddb_resource):
if not ddb_resource:
ddb_resource = boto3.resource('dynamodb')
self.table = ddb_resource.Table(self.table_name)
def create_user(self, username):
return self.table.put_item(Item={'id': str(uuid4), 'username': username})
@mock_dynamodb2
class TestUserRepository(TestCase):
def setUp(self):
ddb = boto3.resource("dynamodb", "us-east-1")
self.table = ddb.create_table(**create_user_table('users'))
self.test_user_repo = UserRepository(ddb)
def tearDown(self):
self.table.delete()
def test_some_thing_success(self):
user = self.test_user_repo.create_user(username='John')
assert len(self.table.scan()['Items']) == 1
def test_some_thing_failure(self):
self.test_user_repo.table = table = Mock()
table.put_item.side_effect = Exception('Boto3 Exception')
with self.assertRaises(Exception) as exc:
self.test_user_repo.create_user(username='John')
self.assertTrue('Boto3 Exception' in exc.exception)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.