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

如何通过Mock确定性测试非确定性函数的异常?断言方式是否正确?

关于Mock触发异常测试及异常验证的解答

一、你的Mock实现是正确的

你当前的测试代码已经可以通过Mock myfuncs.func_a 返回{"input": 0}来确定性触发异常,不需要反复调用碰运气。这段代码逻辑没问题,执行后会进入func_c的except ZeroDivisionError分支,抛出你定义的异常。

二、断言错误消息的方式可行,但可以更健壮

当前方式的合理性

直接断言错误消息内容是有效的验证手段,能确认抛出的是预期的异常而非其他意外错误。不过有两个优化点:

  1. 避免精确匹配全字符串:如果后续修改错误消息的细节(比如标点、措辞),精确匹配会导致测试失败。建议用assert "关键词" in str(e)的方式,你用的startswith也可以,只要能匹配核心信息即可。
  2. 优先使用自定义异常类:抛出通用的Exception不够精准,可能会捕获到其他地方意外抛出的Exception。更严谨的做法是定义专属异常类:

优化方案:自定义异常类

  1. 在myfuncs.py中添加自定义异常:
class ZeroSumDivisionError(Exception):
    """当func_a返回0导致除零错误时抛出的异常"""
    pass
  1. 修改func_c的异常抛出逻辑:
def func_c(z):
    bz = func_b(z)
    scale_x = bz['b_input'] = copy.deepcopy(bz['input'])
    try:
        bz['input'] = scale_x / (scale_x *2)**2
    except ZeroDivisionError as e:
        # 使用raise ... from e保留异常链,便于调试
        raise ZeroSumDivisionError("You've lucked out, the pick from func_a gave you 0!") from e
    return bz
  1. 测试时直接断言异常类型(更精准):
    用pytest的写法:
from mock import patch
import pytest
from myfuncs import func_c, ZeroSumDivisionError

def test_func_c_zero_sum_exception():
    with patch("myfuncs.func_a", return_value={"input": 0}):
        # 精准捕获自定义异常类
        with pytest.raises(ZeroSumDivisionError) as exc_info:
            func_c(12)
        # 可选:验证消息内容
        assert "You've lucked out" in str(exc_info.value)

用unittest的写法:

import unittest
from mock import patch
from myfuncs import func_c, ZeroSumDivisionError

class TestFuncC(unittest.TestCase):
    def test_zero_sum_division_exception(self):
        with patch("myfuncs.func_a", return_value={"input": 0}):
            with self.assertRaises(ZeroSumDivisionError) as context:
                func_c(12)
            self.assertIn("You've lucked out", str(context.exception))

总结

  • 你当前的Mock实现完全可以实现确定性异常测试,无需修改;
  • 断言错误消息内容是有效的,但自定义异常类+断言异常类型的方式更健壮、更易维护;
  • 若暂时不想定义自定义异常,保留当前的消息断言逻辑即可,建议用包含关键词的匹配方式替代精确匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:27:07