如何为通过boto3导入的Cognito客户端编写单元测试
测试实现方案
正常场景测试(无错误返回)
使用Python标准库自带的unittest.mock模块即可完成boto3的mock,核心逻辑是替换boto3.client的返回值,将admin_add_user_to_group方法设置为无异常的空实现,测试代码示例如下:
import unittest from unittest.mock import patch, MagicMock from your_module import run_cognito_client # 替换为实际的模块导入路径 class TestCognitoClient(unittest.TestCase): @patch("your_module.boto3") # 替换为待测试代码中boto3的导入路径 def test_normal_call(self, mock_boto3): # 构造mock的cognito客户端 mock_cognito_client = MagicMock() mock_boto3.client.return_value = mock_cognito_client # 调用待测试方法 run_cognito_client("test_pool_id", "test_username", "test_group") # 验证调用参数符合预期 mock_boto3.client.assert_called_once_with("cognito-idp") mock_cognito_client.admin_add_user_to_group.assert_called_once_with( UserPoolId="test_pool_id", Username="test_username", GroupName="test_group" )
异常场景测试
你当前测试触发其他异常的核心原因大概率是:Python3不支持直接抛出字符串类型,原代码中raise (e.response['Error']['Message'])的写法会直接触发TypeError: exceptions must derive from BaseException,而非预期的错误信息。
先修改原代码的异常抛出逻辑:
from botocore.exceptions import ClientError import boto3 def run_cognito_client(user_pool_id, username, group_name): try: cognito_client = boto3.client('cognito-idp') cognito_client.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name) except ClientError as e: # 改为抛出标准异常类实例,避免类型错误 raise RuntimeError(e.response['Error']['Message']) from e
之后编写异常测试用例,构造符合结构的ClientError实例触发异常分支:
from botocore.exceptions import ClientError @patch("your_module.boto3") def test_error_call(self, mock_boto3): mock_cognito_client = MagicMock() mock_boto3.client.return_value = mock_cognito_client # 构造标准ClientError异常 expect_err_msg = "目标用户不存在" test_client_error = ClientError( { "Error": { "Message": expect_err_msg, "Code": "UserNotFoundException" } }, "AdminAddUserToGroup" ) mock_cognito_client.admin_add_user_to_group.side_effect = test_client_error # 验证异常抛出符合预期 with self.assertRaisesRegex(RuntimeError, expect_err_msg): run_cognito_client("test_pool_id", "test_username", "test_group")
注意事项
- mock boto3时的路径必须和待测试代码中导入boto3的路径完全一致,如果待测试代码中是在
user_ops.py里导入的boto3,就写@patch("user_ops.boto3"),不要直接patch全局根路径的boto3 - 如果不想修改原代码的异常抛出逻辑,测试时需要捕获TypeError,但非常不推荐保留直接raise字符串的写法
内容的提问来源于stack exchange,提问作者L44TXF
相关产品推荐
相关产品推荐

