我正在尝试模拟boto3 s3客户端对象中的单个方法,以抛出异常。但我需要所有其他方法才能让这个类正常工作。
这样我就可以在执行upload_part_copy时出现错误时测试单个异常测试
第一次尝试
import boto3
from mock import patch
with patch('botocore.client.S3.upload_part_copy', side_effect=Exception('Error Uploading')) as mock:
client = boto3.client('s3')
# Should return actual result
o = client.get_object(Bucket='my-bucket', Key='my-key')
# Should return mocked exception
e = client.upload_part_copy()
但是,这会产生以下错误:
ImportError: No module named S3
第二次尝试
在查看了botocore.client.py源代码之后,我发现它做了一些聪明的事情,而upload_part_copy
方法并不存在。我发现它似乎调用的是BaseClient._make_api_call
,所以我试着模拟一下
import boto3
from mock import patch
with patch('botocore.client.BaseClient._make_api_call', side_effect=Exception('Error Uploading')) as mock:
client = boto3.client('s3')
# Should return actual result
o = client.get_object(Bucket='my-bucket', Key='my-key')
# Should return mocked exception
e = client.upload_part_copy()
这抛出了一个异常...但是在我想要避免的get_object
上。
关于为什么我只能在upload_part_copy
方法上抛出异常,有什么想法吗?
发布于 2019-04-05 09:51:49
我不得不模拟boto3
客户端进行一些集成测试,这有点痛苦!我遇到的问题是moto
不能很好地支持KMS
,但我不想为S3
桶重写自己的mock。所以我创造了所有答案的变形。此外,它在全球范围内工作,这是非常酷的!
我有它与2个文件设置。
第一个是aws_mock.py
。对于KMS
模拟,我从实时boto3
客户端获得了一些预定义的响应。
from unittest.mock import MagicMock
import boto3
from moto import mock_s3
# `create_key` response
create_resp = { ... }
# `generate_data_key` response
generate_resp = { ... }
# `decrypt` response
decrypt_resp = { ... }
def client(*args, **kwargs):
if args[0] == 's3':
s3_mock = mock_s3()
s3_mock.start()
mock_client = boto3.client(*args, **kwargs)
else:
mock_client = boto3.client(*args, **kwargs)
if args[0] == 'kms':
mock_client.create_key = MagicMock(return_value=create_resp)
mock_client.generate_data_key = MagicMock(return_value=generate_resp)
mock_client.decrypt = MagicMock(return_value=decrypt_resp)
return mock_client
第二个是实际的测试模块。让我们称它为test_my_module.py
。我省略了my_module
的代码。以及正在测试的函数。让我们调用这些foo
,bar
函数。
from unittest.mock import patch
import aws_mock
import my_module
@patch('my_module.boto3')
def test_my_module(boto3):
# Some prep work for the mock mode
boto3.client = aws_mock.client
conn = boto3.client('s3')
conn.create_bucket(Bucket='my-bucket')
# Actual testing
resp = my_module.foo()
assert(resp == 'Valid')
resp = my_module.bar()
assert(resp != 'Not Valid')
# Etc, etc, etc...
还有一件事,我不确定这个问题是否得到了解决,但我发现,除非您设置一些环境变量,如凭据和区域,否则moto
并不满意。它们不一定是实际的凭据,但需要进行设置。当你读到这篇文章的时候,它可能已经修复了!但这里有一些代码,以防您确实需要它,这一次是shell代码!
export AWS_ACCESS_KEY_ID='foo'
export AWS_SECRET_ACCESS_KEY='bar'
export AWS_DEFAULT_REGION='us-east-1'
我知道它可能不是最漂亮的代码,但是如果你正在寻找一些通用的东西,它应该工作得很好!
https://stackoverflow.com/questions/37143597
复制相似问题