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

pytest异常单元测试如何mock被测函数内部调用的函数

mock同模块函数的实现方法

直接用Python标准库自带的unittest.mock就能实现,不需要额外安装依赖;如果习惯用pytest生态的插件,也可以用pytest-mock简化写法。核心要注意patch路径的写法,这是绝大多数人mock不生效的原因。

核心规则

patch的路径必须写被测函数调用目标函数时的查找路径,简单说就是:check_name在哪个模块里调用create_list,就patch哪个模块下的create_list引用。
你的check_name和create_list都在src.sp_api.api.sp模块下,check_name直接调用同模块的create_list,所以patch路径必须是src.sp_api.api.sp.create_list,写错路径就会导致真实函数依然被执行。

标准库实现(无需额外装包)

修改test_sp.py的测试代码如下:

import pytest
from unittest.mock import patch, Mock
from src.sp_api.api.sp import check_name, NameExists

def test_exception_existed_name(self):
    # 构造假返回数据
    mock_apps = []
    for app_name in ["p", "r", "g", "x"]:
        fake_app = Mock()
        fake_app.name = app_name
        mock_apps.append(fake_app)
    mock_resp = Mock()
    mock_resp.details = mock_apps

    # patch对应路径下的create_list,替换为mock对象
    with patch("src.sp_api.api.sp.create_list") as mock_create_list:
        mock_create_list.return_value = mock_resp
        # 执行被测逻辑
        with pytest.raises(NameExists):
            check_name(token="test_token", name="g")
    
    # 可选校验:确认create_list被正确调用
    mock_create_list.assert_called_once_with("test_token")
  • 如果你觉得用Mock对象不够直观,也可以自己写简单的类来模拟返回结构,效果完全一致:
class MockApp:
    def __init__(self, name):
        self.name = name

class MockResponse:
    def __init__(self, details):
        self.details = details

# 构造数据时换成自定义类即可
mock_apps = [MockApp(name=n) for n in ["p", "r", "g", "x"]]
mock_resp = MockResponse(details=mock_apps)

pytest-mock简化写法

如果你安装了pytest-mock插件,可以直接用mocker夹具,省去手动写上下文管理器的步骤:

import pytest
from unittest.mock import Mock
from src.sp_api.api.sp import check_name, NameExists

def test_exception_existed_name(self, mocker):
    # 构造假数据逻辑和上面完全一致
    mock_apps = []
    for app_name in ["p", "r", "g", "x"]:
        fake_app = Mock()
        fake_app.name = app_name
        mock_apps.append(fake_app)
    mock_resp = Mock()
    mock_resp.details = mock_apps

    mock_create_list = mocker.patch(
        "src.sp_api.api.sp.create_list", 
        return_value=mock_resp
    )

    with pytest.raises(NameExists):
        check_name(token="test_token", name="g")
    
    mock_create_list.assert_called_once_with("test_token")

注意:如果运行测试时提示找不到src模块,在tests目录下新建conftest.py,把项目根目录加入Python导入路径即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 07:09:18