如何在boto3+moto单元测试中覆盖ClientError异常分支
如何覆盖待办事项脚本中ClientError异常分支的测试
问题背景
我有一个基于模拟AWS基础设施的待办事项Python脚本,其中put_item函数包含ClientError异常处理逻辑,但现有单元测试始终无法覆盖这部分代码:
原脚本中未被覆盖的代码:
except ClientError as e: print(e.response['Error']['Message'])
现有测试的核心问题是没有构造出能触发ClientError的场景,导致异常分支从未执行。
解决方案:构造触发ClientError的测试场景
要覆盖该分支,需要让table.put_item()调用抛出ClientError,以下是两种简单可行的实现方式:
方式1:模拟主键冲突(最直接)
通过固定UUID生成值,让两次写入使用同一个主键,触发DynamoDB的主键唯一性约束错误,从而抛出ClientError。
修改测试代码,新增测试用例:
- 先导入
unittest.mock的patch工具:
from unittest.mock import patch
- 添加测试函数:
def test_put_item_duplicate_key_error(self): print ('---------------------') print ('Start: test_put_item_duplicate_key_error') from src.todoList import put_item # 固定uuid返回值,确保两次写入用同一个id with patch('src.todoList.uuid.uuid1') as mock_uuid: mock_uuid.return_value = self.uuid # 第一次写入成功 first_response = put_item(self.text, self.dynamodb) self.assertEqual(200, first_response['statusCode']) # 第二次写入同一个id,触发主键冲突的ClientError second_response = put_item(self.text, self.dynamodb) # 异常被捕获后函数无返回值(若原脚本未修改) self.assertIsNone(second_response) print ('End: test_put_item_duplicate_key_error')
方式2:操作不存在的表
临时修改环境变量,让get_table指向一个未创建的表,触发ResourceNotFoundException(属于ClientError子类)。
新增测试用例:
def test_put_item_nonexistent_table(self): print ('---------------------') print ('Start: test_put_item_nonexistent_table') from src.todoList import put_item # 临时替换环境变量中的表名 original_table = os.environ.get('DYNAMODB_TABLE') os.environ['DYNAMODB_TABLE'] = 'non-existent-todo-table' try: response = put_item(self.text, self.dynamodb) self.assertIsNone(response) finally: # 恢复原环境变量,避免影响其他测试 if original_table: os.environ['DYNAMODB_TABLE'] = original_table else: del os.environ['DYNAMODB_TABLE'] print ('End: test_put_item_nonexistent_table')
现有测试的修正提示
你当前的test_put_todo_error用例写法错误:
self.assertRaises(Exception, put_item("", self.dynamodb))
该代码会直接执行put_item,而非传递可调用对象给assertRaises,正确写法应为:
self.assertRaises(Exception, put_item, "", self.dynamodb)
但注意:原脚本中put_item已经捕获了ClientError,不会向外抛出异常,所以这个测试的逻辑本身不成立,建议删除或调整为验证异常分支的行为(比如验证错误日志输出)。
内容的提问来源于stack exchange,提问作者javier
相关产品推荐
相关产品推荐

