如何在单元测试中模拟 ParameterNotFound boto3 异常?

Sha*_*awn 3 python unit-testing python-unittest boto3

我想测试一些错误处理逻辑,所以我想在单元测试中模拟特定的异常类型。我正在模拟对 boto3 的调用,但我想进行该模拟以引发异常ParameterNotFound。我正在测试的代码遵循以下模式

boto3_client = boto3.client('ssm')
try:
    temp_var = boto3_client.get_parameter(Name="Something not found")['Parameter']['Value']
except boto3_client.exceptions.ParameterNotFound:
    ... [logic I want to test]
Run Code Online (Sandbox Code Playgroud)

我创建了一个单元测试模拟,但我不知道如何使其引发异常作为此 ParameterNotFound 异常。我尝试了以下方法,但它不起作用,因为在评估 except 子句时它得到“异常必须从基类派生”:

@patch('patching_config.boto3.client')
def test_sample(self, mock_boto3_client):
        mock_boto3_client.return_value = mock_boto3_client

        def get_parameter_side_effect(**kwargs):
            raise boto3.client.exceptions.ParameterNotFound()

        mock_boto3_client.get_parameter.side_effect = get_parameter_side_effect
Run Code Online (Sandbox Code Playgroud)

如何在单元测试中模拟 ParameterNotFound boto3 异常?

Sha*_*awn 6

我认为问题是我对 boto3 如何引发异常的误解。我在这里找到了一个解释: https: //github.com/boto/boto3/issues/1262在“ClientError 的结构”下

ClientError 的结构

在 ClientError(但不是 BotoCoreError)中,将有一个 operation_name 属性(应该是 str)和一个 response 属性(应该是 dict)。响应属性应具有以下形式(来自格式错误的 ec2.DescribeImages 调用的示例):

也在这里:https ://codeday.me/en/qa/20190306/12210.html

{
    "Error": {
        "Code": "InvalidParameterValue",
        "Message": "The filter 'asdfasdf' is invalid"
    },
    "ResponseMetadata": {
        "RequestId": "aaaabbbb-cccc-dddd-eeee-ffff00001111",
        "HTTPStatusCode": 400,
        "HTTPHeaders": {
            "transfer-encoding": "chunked",
            "date": "Fri, 01 Jan 2100 00:00:00 GMT",
            "connection": "close",
            "server": "AmazonEC2"
        },
        "RetryAttempts": 0
    }
}
Run Code Online (Sandbox Code Playgroud)

听起来异常是作为 ClientError 抛出的,它有 ParameterNotFound 错误代码,所以我需要将其更改为

from botocore.exceptions import ClientError
Run Code Online (Sandbox Code Playgroud)

进而

except ClientError as e:
Run Code Online (Sandbox Code Playgroud)

在模拟中,我需要引发一个 ClientError ,而不是使用 ParameterNotFound 作为代码:

raise botocore.exceptions.ClientError({"Error": {"Code": "ParameterNotFound",
                                                 "Message": "Parameter was not found"}}, 
                                      'get_parameter')
Run Code Online (Sandbox Code Playgroud)