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

如何用pytest Mock subprocess.run返回值?解决测试TypeError问题

问题分析与解决

错误原因

你在Mock subprocess.run返回的进程对象时,错误地使用了returncode.return_value来配置属性。returncode是subprocess.CompletedProcess的直接属性(不是可调用方法),不需要加.return_value。原写法会让mock_proc.returncode变成一个MagicMock对象,而非整数0,导致和整数比较时抛出类型错误。

修正后的unittest.mock写法

直接在configure_mock里设置returncode=0,同时stdout也是属性,同样不需要.return_value:

from unittest.mock import MagicMock, patch

import pytest

from pybmx.bmx import Bmx


@patch('pybmx.bmx.subprocess.run')
def test_version(mock_run):
    mock_proc = MagicMock()
    mock_proc.configure_mock(**{
        'returncode': 0,
        'stdout': 'raw2bmx, bmx v1.1.6, Mar  3 2023 10:02:28 (scm v1.1-6-g43fac95-dirty)',
        'stderr': ''  # 可选,_run返回stderr,这里设为空字符串即可
    })
    mock_run.return_value = mock_proc
    assert Bmx('raw2bmx').version() == (1, 1, 6)

不用unittest,直接用pytest的方案

可以使用pytest-mock插件(先安装:pip install pytest-mock),它封装了unittest.mock,提供更简洁的mocker fixture,无需导入patch:

import pytest

from pybmx.bmx import Bmx


def test_version(mocker):
    # Mock subprocess.run
    mock_run = mocker.patch('pybmx.bmx.subprocess.run')
    # 配置返回的进程对象
    mock_run.return_value = mocker.Mock(
        returncode=0,
        stdout='raw2bmx, bmx v1.1.6, Mar  3 2023 10:02:28 (scm v1.1-6-g43fac95-dirty)',
        stderr=''
    )
    assert Bmx('raw2bmx').version() == (1, 1, 6)

额外测试分支示例

如果需要测试错误分支(returncode>0的情况),可以设置returncode=1,并断言BmxError是否被正确抛出:

def test_version_error(mocker):
    mock_run = mocker.patch('pybmx.bmx.subprocess.run')
    mock_run.return_value = mocker.Mock(
        returncode=1,
        stderr='some error message'
    )
    with pytest.raises(BmxError) as excinfo:
        Bmx('raw2bmx').version()
    assert excinfo.value.args[0] == 'some error message'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 21:05:29