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

时间:2019-07-26 21:30:25

标签: python unit-testing boto3 python-unittest

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

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]

我已经创建了一个unittest模拟,但是我不知道如何使它引发此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

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

1 个答案:

答案 0 :(得分:1)

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

  

ClientError的结构

     

在ClientError(但不是BotoCoreError)中,将会有一个   operation_name属性(应为str)和response属性   (应该是字典)。响应属性应具有以下内容   形式(例如来自格式错误的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
    }
}

我听起来像是抛出了带有ParameterNotFound代码的ClientError引发异常,所以我需要将代码更改为

from botocore.exceptions import ClientError

然后

except ClientError as e:

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

raise botocore.exceptions.ClientError({"Code": "ParameterNotFound","Message": "The parameter was not found"}, {...})