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

如何Mock Python的subprocess.check_output多不同调用?报错排查

问题分析与解决

你遇到的错误根源是误解了new_callable的作用:它的参数需要是一个创建Mock对象的工厂函数(比如MagicMock),而不是直接作为被替换的函数使用。你的代码中,当mocker.patch调用my_outputs时没有传入任何参数,导致args为空,函数返回None,最终subprocess.check_output被替换成了None,调用自然会抛出NoneType不可调用的错误。

正确实现方式

要根据传入参数动态返回不同结果,应该使用Mock对象的side_effect属性——它可以绑定一个函数,每次Mock被调用时都会执行这个函数,并返回对应结果。

修正后的代码

@pytest.fixture
def mock_check_output(mocker):
    def dynamic_return(*args, **kwargs):
        # 提取调用时传入的命令列表
        cmd = args[0]
        if cmd[0] == "readelf":
            # 注意:check_output返回字节流,需和真实返回类型一致
            return b"fake_readelf_content\n.interp: /lib/ld-linux.so.2"
        elif cmd[0] == "ldd":
            return b"fake_ldd_output"
        else:
            return b"fake_firmware_paths"
    
    # 先patch掉check_output,得到Mock对象
    mock = mocker.patch("subprocess.check_output")
    # 给Mock绑定动态返回逻辑
    mock.side_effect = dynamic_return
    return mock

def test_qemu_overlay(tuxrun_args_qemu_overlay, lava_run, mock_check_output):
    main()
    # 可选:验证check_output是否按预期被调用
    mock_check_output.assert_called_with(["readelf", "-p", ".interp", "qemu_binary"])

关键说明

  1. side_effect的作用:它接受一个函数,该函数会接收Mock被调用时的所有参数,你可以根据这些参数判断应该返回什么模拟数据。
  2. 返回类型匹配:真实的subprocess.check_output返回字节串(bytes),所以你的模拟返回值也必须是字节串,否则后续的.decode("utf-8")会报错。
  3. Mock验证:测试中可以通过assert_called_with或assert_called_once等方法,验证check_output是否被正确调用,确保你的业务逻辑符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 13:02:34