You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python单元测试如何配置Mock让异常仅在被测函数调用时抛出

问题说明

编写Python单元测试测试Google Calendar API调用逻辑时,需要构造接口返回400的异常场景,要求仅当被测函数内部调用execute()方法时才抛出HttpError,进入异常捕获分支。

现有代码存在两个核心问题:

  • 提前在测试准备阶段实例化了带400状态的HttpMock对应的service,会导致测试执行到实例化步骤就直接抛出异常,不会等到被测函数逻辑运行
  • 将execute()的return_value设置为lambda函数,调用execute()时只会返回lambda对象本身,不会执行lambda内部的异常逻辑,因此无法触发预期的400错误
解决方案

使用Mock对象的side_effect参数替代return_value实现异常触发:side_effect定义的内容会在Mock方法被实际调用时自动执行——如果传入异常类/实例,调用时直接抛出对应异常;如果传入可调用对象(比如lambda),调用时会自动执行该对象逻辑。

方式1:结合官方HttpMock触发真实400响应

@patch("add_entry_to_calendar.build")
def test_add_entry_to_calendar_400(self, mock_build):
    # 初始化返回400状态的HttpMock
    http = HttpMock('tests/config-test.json', {'status': '400'})
    
    # 获取patch生成的mock service实例,不需要提前调用真实build
    mock_service = mock_build.return_value
    # 给execute方法设置side_effect,调用execute时自动执行lambda触发400异常
    # 注意lambda参数和实际调用保持一致,被测代码中execute无入参,所以lambda不加形参
    mock_service.events.return_value.insert.return_value.execute.side_effect = \
        lambda: build("calendar", "v3", http=http).events().insert(calendarId='primary').execute(http=http)
    
    # 调用被测函数,验证异常被捕获后返回None
    self.assertEqual(add_entry_to_calendar({"A":"B"}), None)

方式2:直接构造HttpError(更推荐,测试更稳定高效)

不需要依赖HttpMock和本地配置文件,直接构造异常实例即可,单元测试执行更快,没有外部依赖:

from googleapiclient.errors import HttpError
from unittest.mock import Mock

@patch("add_entry_to_calendar.build")
def test_add_entry_to_calendar_400(self, mock_build):
    # 构造400状态的HttpError实例
    mock_resp = Mock(status=400, reason="Bad Request")
    http_400_error = HttpError(resp=mock_resp, content=b'{"error": "invalid request"}')
    
    mock_service = mock_build.return_value
    # 直接将异常实例赋值给side_effect,调用execute时自动抛出该异常
    mock_service.events.return_value.insert.return_value.execute.side_effect = http_400_error
    
    self.assertEqual(add_entry_to_calendar({"A":"B"}), None)

注意:不要在测试准备阶段手动调用build("calendar", "v3", http=http)生成真实service,这行代码会在测试用例启动时就执行,直接抛出400异常,无法实现被测函数内部调用时才抛错的效果。

内容的提问来源于stack exchange,提问作者Dennis_M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 13:09:26