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

如何通过pytest参数化动态传递被补丁函数测试路由函数

解决方案:参数化测试路由函数的函数调用

要实现同时测试多个输入值对应正确函数的调用,你可以结合pytest.mark.parametrize和unittest.mock通过以下两种方式实现:

方法一:用patch.multiple批量Mock函数

适合测试多个函数的场景,一次性Mock所有可能被调用的函数,再通过参数化指定每个用例要检查的目标函数。

测试代码示例

import pytest
from unittest.mock import patch
import app.handlers as handlers

# 修正后的原路由函数
# def router(value):
#     actions = {
#         "in": in_action,
#         "out": out_action,
#     }
#     actions[value]()

@pytest.mark.parametrize(
    "value, target_func_name, expected_count",
    [
        ("in", "in_action", 1),
        ("out", "out_action", 1),
        ("invalid", None, 0),  # 无效输入,无函数调用
    ]
)
@patch.multiple("app.handlers", in_action=None, out_action=None)
def test_router(value, target_func_name, expected_count, **mocks):
    # 执行路由,捕获无效输入的KeyError
    try:
        handlers.router(value)
    except KeyError:
        pass

    if target_func_name:
        # 获取对应Mock对象并断言调用次数
        mock_func = mocks[target_func_name]
        assert mock_func.call_count == expected_count
    else:
        # 无效输入时,确保所有Mock函数都未被调用
        for mock in mocks.values():
            assert mock.call_count == 0

方法二:逐个Mock函数,动态获取Mock对象

如果需要测试的函数数量较少,可以逐个添加@patch装饰器,再通过参数化指定要检查的Mock对象名称。

测试代码示例

import pytest
from unittest.mock import patch
import app.handlers as handlers

@pytest.mark.parametrize(
    "value, target_mock_name, expected_count",
    [
        ("in", "mock_in_action", 1),
        ("out", "mock_out_action", 1),
        ("invalid", None, 0),
    ]
)
@patch("app.handlers.in_action")
@patch("app.handlers.out_action")
def test_router(mock_out_action, mock_in_action, value, target_mock_name, expected_count):
    try:
        handlers.router(value)
    except KeyError:
        pass

    if target_mock_name:
        # 通过局部变量获取对应Mock对象
        mock_func = locals()[target_mock_name]
        assert mock_func.call_count == expected_count
    else:
        # 验证所有Mock函数都未被调用
        assert mock_in_action.call_count == 0
        assert mock_out_action.call_count == 0

关键说明

  • 处理无效输入:当传入actions中不存在的value时,router会抛出KeyError,需要捕获该异常避免测试失败。
  • 动态Mock对象获取:两种方法都通过参数化指定要检查的目标,避免为每个函数单独编写测试用例,提高代码复用性。
  • 调用次数断言:无论是单个函数还是所有函数,都能精确验证是否被正确调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 10:17:49