如何使用pytest从subprocess.run模拟returncode,stdout,stderr?

How to mock returncode, stdout, stderr from subprocess.run with pytest?

提问人:opnightfall1771 提问时间:4/3/2023 更新时间:4/3/2023 访问量:465

问:

我正在尝试使用 pytest 编写单元测试以模拟调用,遵循此处的其他一些示例,但遇到了困难。我有以下类:subprocess.run

class Bmx:

    def version(self) -> Tuple[int, int, int]:
        cmd = [self.exec_path, '-v']
        err, out = self._run(cmd)
        version = re.search(r'v\d+\.\d+\.\d+', out, re.IGNORECASE)[0][1:].split('.')
        return int(version[0]), int(version[1]), int(version[2])

    @staticmethod
    def _run(cmd: List[str], shell: bool = False) -> Tuple[str, str]:
        proc = subprocess.run(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=shell, universal_newlines=True)
        if proc.returncode > 0:
            raise BmxError(proc.stderr)
        return proc.stderr, proc.stdout

我尝试为该方法编写一个单元测试,如下所示:version

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.return_value': 0,
        'stdout.return_value': 'raw2bmx, bmx v1.1.6, Mar  3 2023 10:02:28 (scm v1.1-6-g43fac95-dirty)'
    })
    mock_run.return_value = mock_proc
    assert Bmx('raw2bmx').version() == (1, 1, 6)

但是,测试失败,并出现以下情况:

    @staticmethod
    def _run(cmd: List[str], shell: bool = False) -> Tuple[str, str]:
        proc = subprocess.run(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=shell, universal_newlines=True)
>       if proc.returncode > 0:
E       TypeError: '>' not supported between instances of 'MagicMock' and 'int'

我以为通过使用 MagicMock 方法配置我会模拟返回代码,但似乎我没有正确理解这一点。我也想知道是否有办法实现这一目标,而不是.任何建议将不胜感激!谢谢。returncode.return_valueconfigurepytestunittest

python 单元测试 模拟子 进程 pytest

评论


答:

2赞 Baumkuchen 4/3/2023 #1

问题似乎是用于模拟方法,但是一个属性。 不过,模拟属性甚至更容易(参见文档):mock_proc.configure_mock(**{"f.return_value": ...})proc.returncode

>>> m = MagicMock(attribute=3, other='fish')
>>> m.attribute
3
>>> m.other
'fish'