【问题标题】:How to Mock: pytest.raises DID NOT RAISE <class 'subprocess.TimeoutExpired'>如何模拟:pytest.raises DID NOT RAISE <class 'subprocess.TimeoutExpired'>
【发布时间】:2020-10-02 02:39:44
【问题描述】:

我正在使用subprocess 执行任务,并且我有一个try/except 块用于捕获TimeoutExpired。我尝试使用side_effect 模拟我的对象,这样我就可以使用pytest.raises 捕获虚假异常。无论我做什么,我都会得到DID NOT RAISE &lt;class 'subprocess.TimeoutExpired'&gt;。 我尝试了很多事情,尽管我对嘲讽的经验并不丰富,但我相信这样的事情原则上应该可行:

# my_check.py
from subprocess import TimeoutExpired, PIPE, check_output

class Check:
    def __init__(self, name):
        self.name = name
        self.status = self.get_status()

    def get_status(self):
        try:
            out = check_output(["ls"], universal_newlines=True, stderr=PIPE, timeout=2)
        except TimeoutExpired as e:
            print(f"Command timed out: {e}")
            raise

        if self.name in out:
            return True
        return False


# test_my_check.py
import pytest
from unittest import mock
from subprocess import TimeoutExpired

@mock.patch("src.my_check.Check", autospec=True)
def test_is_installed_exception(check_fake):
    check_fake.get_status.side_effect = TimeoutExpired
    obj_fake = check_fake("random_file.txt")
    with pytest.raises(TimeoutExpired):
        obj_fake.get_status()

由于某种原因,它不起作用,而且我无法弄清楚出了什么问题。

【问题讨论】:

    标签: python mocking subprocess pytest try-except


    【解决方案1】:

    如果你想测试一个类 (Check) 的功能,你不能模拟那个类。您必须模拟您想要更改的调用 - 在这种情况下可能是 check_output,您想要引发异常:

    @mock.patch("src.my_check.check_output")
    def test_is_installed_exception(mocked_check_output):
        mocked_check_output.side_effect = TimeoutExpired("check_output", 1)
        with pytest.raises(TimeoutExpired):
            Check("random_file.txt")
    

    一些注意事项:

    • 你必须修补“src.my_check.check_output”,因为你使用from subprocess import check_output导入check_output,所以你在你的类中使用参考
    • 您必须构造一个有效的 TimeoutExpired 对象 - 它需要 2 个参数,因此您必须提供它们
    • 由于 get_status 已在 __init__ 中调用,您必须测试类构造 - 由于引发异常,您无法获得正确构造的实例

    【讨论】:

      猜你喜欢
      • 2020-12-03
      • 2022-12-28
      • 1970-01-01
      • 1970-01-01
      • 2019-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-16
      相关资源
      最近更新 更多