当前位置: 首页 > 知识库问答 >
问题:

模拟boto3 S3客户端方法Python

边桐
2023-03-14

我试图从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\u part\u copy不存在。我发现它似乎调用BaseClient.\u make\u api\u 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_对象上。

关于如何只能在upload\u part\u copy方法上抛出异常,有什么想法吗?


共有3个答案

谢承颜
2023-03-14

下面是一个简单的python单元测试示例,可用于伪造client=boto3.client('ec2')api调用。。。

import boto3 

class MyAWSModule():
    def __init__(self):
        client = boto3.client('ec2')
        tags = client.describe_tags(DryRun=False)


class TestMyAWSModule(unittest.TestCase):
    @mock.patch("boto3.client.get_tags")
    @mock.patch("boto3.client")
    def test_open_file_with_existing_file(self, mock_boto_client, mock_describe_tags):
        mock_describe_tags.return_value = mock_get_tags_response
        my_aws_module = MyAWSModule()

        mock_boto_client.assert_call_once('ec2')
        mock_describe_tags.assert_call_once_with(DryRun=False)

mock_get_tags_response = {
    'Tags': [
        {
            'ResourceId': 'string',
            'ResourceType': 'customer-gateway',
            'Key': 'string',
            'Value': 'string'
        },
    ],
'NextToken': 'string'
}

希望这能有所帮助。

许俊风
2023-03-14

我一在这里发帖,就设法想出了一个解决办法。这里是希望它有帮助:)

import botocore
from botocore.exceptions import ClientError
from mock import patch
import boto3

orig = botocore.client.BaseClient._make_api_call

def mock_make_api_call(self, operation_name, kwarg):
    if operation_name == 'UploadPartCopy':
        parsed_response = {'Error': {'Code': '500', 'Message': 'Error Uploading'}}
        raise ClientError(parsed_response, operation_name)
    return orig(self, operation_name, kwarg)

with patch('botocore.client.BaseClient._make_api_call', new=mock_make_api_call):
    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()

Jordan Philips还发布了一个使用botocore.stub.Stubber类的伟大解决方案。虽然是一个更干净的解决方案,但我无法嘲笑特定的操作。

卫阳炎
2023-03-14

Botocore有一个客户端存根,您可以将其用于以下目的:文档。

下面是一个输入错误的例子:

import boto3
from botocore.stub import Stubber

client = boto3.client('s3')
stubber = Stubber(client)
stubber.add_client_error('upload_part_copy')
stubber.activate()

# Will raise a ClientError
client.upload_part_copy()

下面是一个将正常响应放入的示例。此外,stubber现在可以在上下文中使用。需要注意的是,stuber将尽可能验证您提供的响应是否与服务实际返回的内容匹配。这并不完美,但它可以保护您避免插入完全无意义的响应。

import boto3
from botocore.stub import Stubber

client = boto3.client('s3')
stubber = Stubber(client)
list_buckets_response = {
    "Owner": {
        "DisplayName": "name",
        "ID": "EXAMPLE123"
    },
    "Buckets": [{
        "CreationDate": "2016-05-25T16:55:48.000Z",
        "Name": "foo"
    }]
}
expected_params = {}
stubber.add_response('list_buckets', list_buckets_response, expected_params)

with stubber:
    response = client.list_buckets()

assert response == list_buckets_response
 类似资料:
  • 问题内容: 我正在尝试从boto3 s3客户端对象模拟一个单独的方法来引发异常。但是我需要所有其他方法来使此类正常工作。 这样一来,我可以在执行upload_part_copy并发生错误时测试单个异常测试 第一次尝试 但是,这将产生以下错误: 第二次尝试 查看botocore.client.py源代码后,我发现它做的很聪明,并且该方法不存在。我发现似乎要打电话给我,所以我试图模拟 这引发了异常…但

  • URI 方法 URI() string 返回当前客户端使用的服务器地址。 SetURI 方法 SetURI(uri string) 设置当前客户端使用的服务器地址。如果你想要设置多个服务器地址,请使用 SetURIList 方法代替该方法。 URIList 方法 URIList() []string 返回当前客户端可使用的服务器地址列表。 SetURIList 方法 SetURIList(uriL

  • 我正在测试一个Springmvc控制器,它得到一个网络服务客户端自动配带,它被嘲笑了。但是嘲笑并没有奏效。在测试返回中调用“验证(stuClient,乘以(1))”。获取所有学生(sAndP命令); 下面是我测试中的控制器方法: 下面是我的测试类:

  •  说明 判断是否安装游戏 $.f2eMb.app.checkInstall(pckName) 下载游戏 $.f2eMb.app.dwGame(gameId) 根据地址下载游戏 $.f2eMb.app.dwGameByUrl(url,gameId,pckName) 进入游戏 $.f2eMb.app.strGame(pckName) 登录 $.f2eMb.app.login() 复制 $.f2eMb

  • 我正在使用spring Cloud的eureka和feign在一些服务之间进行通信(比如A和B)。现在我想统一测试一个服务(a)的服务层。问题是,这个服务(A)正在使用一个假客户机来请求其他服务(B)的一些信息。 编辑:我最终为虚假客户机创建了一个存根。存根被标记为主要组件,以强制spring在我的测试中实例化存根。 这是我提出的解决方案。

  • 上面还有第二个问题。当我在Expects块中定义mock类时(如上),似乎只调用了构造函数,而不是,因此没有正确初始化对象。我通过将它移到方法中并在那里实例化该类来解决这个问题。看起来是这样的: 因此,这似乎得到了要调用的正确构造函数,但似乎还在调用。有什么见解吗?