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

如何在pytest中为read_all_rows实现条件化Mock返回值?

基于pytest-mocker的参数化Mock返回方案

你可以通过Python标准库的unittest.mock工具,配合pytest-mocker实现简洁的参数匹配式Mock返回,无需编写复杂的side_effect函数,每个匹配规则可单独一行配置。

原生方案(无需额外依赖)

1. 导入匹配工具

从标准库中导入用于参数匹配的核心组件:

from unittest.mock import call, ANY

其中ANY对应你需求中的any_string(),可匹配任意字符串类型的参数。

2. 配置Mock规则

先patch目标方法获取Mock实例,再通过字典定义参数组合与返回值的对应关系,字典键用call()封装参数:

# 将目标方法替换为Mock对象
mock_read = mocker.patch('db_access.read_all_rows')

# 每行一个匹配规则,清晰直观
mock_read.side_effect = {
    call('table_name1', ANY): ['testRow1'],
    call('table_name2', 'mode1'): ['testRow2', 'tableRow3'],
    call('table_name2', 'mode2'): ['testRow2', 'tableRow3'],
}

当read_all_rows被调用时,会自动匹配对应的参数组合返回预设值;若出现未匹配的参数调用,会抛出KeyError。如果需要默认返回值,可额外处理:

# 定义未匹配参数时的默认返回逻辑
def default_return(*args):
    return []

# 改写side_effect为带默认值的逻辑
mock_read.side_effect = lambda *args: mock_read.match_rules.get(call(*args), default_return(*args))
# 单独存放匹配规则,保持可读性
mock_read.match_rules = {
    call('table_name1', ANY): ['testRow1'],
    call('table_name2', 'mode1'): ['testRow2', 'tableRow3'],
    call('table_name2', 'mode2'): ['testRow2', 'tableRow3'],
}

贴近Mockito风格的第三方库方案

如果希望完全复刻Mockito的链式语法,可引入pytest-mockito库(先通过pip install pytest-mockito安装),写法和你的伪代码几乎一致:

from mockito import when, any

# 每行一个规则,完全贴合需求中的伪代码
when(db_access).read_all_rows('table_name1', any()).thenReturn(['testRow1'])
when(db_access).read_all_rows('table_name2', 'mode1').thenReturn(['testRow2', 'tableRow3'])
when(db_access).read_all_rows('table_name2', 'mode2').thenReturn(['testRow2', 'tableRow3'])

验证示例

调用方法时会自动匹配返回:

print(db_access.read_all_rows('table_name1', '任意模式'))  # 输出 ['testRow1']
print(db_access.read_all_rows('table_name2', 'mode1'))     # 输出 ['testRow2', 'tableRow3']

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:40:26