簡體   English   中英

如何模擬:pytest.raises 沒有 RAISE<class 'subprocess.TimeoutExpired'>

[英]How to Mock: pytest.raises DID NOT RAISE <class 'subprocess.TimeoutExpired'>

我正在使用subprocess執行任務,並且我有一個try/except塊用於捕獲TimeoutExpired 我嘗試使用嘲笑我的對象side_effect這樣我就可以趕上與假例外pytest.raises 無論我做什么,我都得到DID NOT RAISE <class 'subprocess.TimeoutExpired'> 我嘗試了很多東西,盡管我對嘲諷沒有那么豐富的經驗,但我相信這樣的事情原則上應該可行:

# 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()

出於某種原因,它不起作用,我無法理解出了什么問題。

如果要測試類 ( 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 import check_output from subprocess import check_output ,所以你在你的類中使用引用
  • 您必須構造一個有效的TimeoutExpired對象 - 它需要 2 個參數,因此您必須提供它們
  • 由於get_status已經在__init__調用,因此您必須測試類構造 - 由於引發的異常,您無法獲得正確構造的實例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM