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

How can I simulate a ParameterNotFound boto3 exception in my unit test?

我想测试一些错误处理逻辑,所以我想在我的单元测试中模拟一个特定的异常类型。我正在模拟对 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]

我已经创建了一个单元测试模拟,但我不知道如何让它引发异常作为这个 ParameterNotFound 异常。我尝试了以下方法,但它不起作用,因为它在评估 except 子句时得到 "exceptions must derive from the base class":

@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 异常?

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

Structure of a ClientError

Within ClientError (but not BotoCoreError), there will be an operation_name attribute (should be a str) and a response attribute (should be a dict). The response attribute should have the following form (example from a malformed ec2.DescribeImages call):

还有这里: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
    }
}

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

from botocore.exceptions import ClientError

然后

except ClientError as e:

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

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