如何mock boto3 secretsmanager客户端get_secret_value返回指定值或抛出异常
问题原因
你现有测试代码的错误是在get_secret_value后多写了括号,相当于你先调用了一次mock的get_secret_value得到了一个临时MagicMock实例,再对这个实例的return_value赋值,这个配置不会作用到原client的get_secret_value方法上,自然拿不到预期的返回值。
正确实现
1. 让get_secret_value返回指定值
from unittest.mock import patch import boto3 from botocore.exceptions import ClientError # 若你的业务代码直接调用boto3.session.Session(),当前patch路径正确 @patch("boto3.session") def test_get_sendgrid_api_key_return_value(mock_session): # 链式获取mock的secretsmanager客户端对象 mock_client = mock_session.Session.return_value.client.return_value # 直接给方法本身的return_value赋值,不要加括号 mock_client.get_secret_value.return_value = {"SecretString": "my-secret"} # 调用业务逻辑 do_stuff() # 可选:校验调用参数是否符合预期 mock_client.get_secret_value.assert_called_once_with(SecretId=sendgrid_api_key_arn)
2. 让get_secret_value抛出指定异常
如果需要抛出异常,给side_effect赋值为你要抛出的异常实例即可:
@patch("boto3.session") def test_get_sendgrid_api_key_throw_error(mock_session): mock_client = mock_session.Session.return_value.client.return_value # 构造需要抛出的ClientError实例,此处为资源不存在异常示例 test_exception = ClientError( error_response={"Error": {"Code": "ResourceNotFoundException", "Message": "Secret not found"}}, operation_name="GetSecretValue" ) mock_client.get_secret_value.side_effect = test_exception # 校验业务代码是否正确处理异常,用pytest可简化为pytest.raises断言 try: do_stuff() except ClientError as e: assert e.response["Error"]["Code"] == "ResourceNotFoundException"
补充说明
如果你的业务代码是通过from boto3.session import Session的方式导入Session类,需要将patch路径改为你业务模块中Session的导入路径,比如@patch("your_module.Session")。
内容的提问来源于stack exchange,提问作者Alan Hay
相关产品推荐
相关产品推荐

