【问题标题】:How can I simulate a ParameterNotFound boto3 exception in my unit test?如何在单元测试中模拟 ParameterNotFound boto3 异常?
【发布时间】:2019-07-26 21:30:25
【问题描述】:

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

【问题讨论】:

  • 这看起来和我回答你的最后一个问题一样。没错,它是 side_effect,但您需要另一个由 client() 函数返回的模拟对象。
  • 这条线不是这样吗? mock_boto3_client.return_value = mock_boto3_client
  • 对不起,我错过了。我会看看你的例子发生了什么
  • 我测试了您的示例,除了 boto3 不提供 ParameterNotFound 异常这一事实之外,该示例还有效。此示例中是否缺少更多内容?
  • 我收到了exceptions must derive from BaseException,但我可以看到 side_effect 正在工作,因为我添加了一个 print 语句。

标签: python unit-testing boto3 python-unittest


【解决方案1】:

我认为问题在于我对 boto3 如何引发异常的误解。我在这里找到了解释:https://github.com/boto/boto3/issues/1262 under "Structure of a ClientError"

ClientError 的结构

在 ClientError(但不是 BotoCoreError)中,会有一个 operation_name 属性(应该是一个 str)和一个响应属性 (应该是一个字典)。响应属性应具有以下内容 表单(来自格式错误的 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({"Error": {"Code": "ParameterNotFound",
                                                 "Message": "Parameter was not found"}}, 
                                      'get_parameter')

【讨论】:

  • 我的经历与以下答案中列出的不同:stackoverflow.com/a/50958676/230055stackoverflow.com/a/48956137/230055。当我尝试except boto3_client.exceptions.ParameterNotFound 时,我得到“异常必须从基类派生”,所以我质疑其他答案是否真的仍然有效。最终,我在上面这个答案中列出的内容对我有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-14
  • 1970-01-01
  • 2013-02-21
相关资源
最近更新 更多