I am using subprocess
for a task, and I have a try/except
block for catching TimeoutExpired
. I try to mock my object using side_effect
so I can catch the fake exception with pytest.raises
. Whatever I do, I get DID NOT RAISE <class 'subprocess.TimeoutExpired'>
. I have tried many things, and even though I'm not so experienced with mocking, I believe something like that should in principle work:
# 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()
For some reason it doesn't work though, and I can't get my head around what's wrong.
If you want to test the functionality of a class ( Check
) you cannot mock that class. You have to mock instead the calls that you want to change - in this case probably check_output
, which you want to raise an exception:
@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")
A few notes:
check_output
using from subprocess import check_output
, so you use the reference in your classTimeoutExpired
object - it requires 2 arguments, so you have to provide themget_status
is already called in __init__
, you have to test the class construction - you can't get a properly constructed instance because of the raised exception
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.