Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I mock Connection & Timeout Error in Python 3?

I am newbie to Python. I am trying to mock exception in my unit test and test my block of code; however exception message is always empty. Is this below recommended way to mock exception? Also how can I make sure exception message is not empty?

import pytest
import requests
from unittest.mock import patch

#Unit Test
@patch('requests.get')
def test_exception(mock_run):
    mock_run.side_effect = requests.exceptions.ConnectionError()
    with pytest.raises(SystemExit) as sys_exit:
       method_to_test()
    assert 'Error ' in str(sys_exit.value) # Here sys_exit.value is always empty

#Method to Test
def method_to_test():
    try:
        response = requests.get('some_url', verify=False, stream=True)
        response.raise_for_status()
    except (requests.exceptions.HTTPError,
            requests.exceptions.ConnectionError,
            requests.exceptions.Timeout) as err:
        msg = f'Failure: {err}' # Here err is always empty
        raise SystemExit(msg)
like image 519
S R Avatar asked Aug 14 '26 15:08

S R


1 Answers

Long story short: You don't get a message because you don't specify one.

You probably want to check for 'Failure: ' instead of 'Error: ', since this is what you prefix the original exception message with. This might be the real problem in your code, not the empty string representation of the exception you raise in your test.

Why is str(err) empty?

Take a look at the class hierarchy:

  • BaseException
  • Exception
  • IOError
  • requests.RequestException
  • requests.ConnectionError

IOError overrides __str__ if more than one argument is given to the constructor, but otherwise the behavior of BaseException applies:

If str() is called on an instance of this class, the representation of the argument(s) to the instance are returned, or the empty string when there were no arguments. https://docs.python.org/3/library/exceptions.html#BaseException

>>> import requests
>>> str(requests.exceptions.ConnectionError())
''
>>> str(requests.exceptions.ConnectionError('foo'))
'foo'
>>> str(requests.exceptions.ConnectionError('foo', 'bar'))
'[Errno foo] bar'

The last example is the behavior defined by the IOError exception.

like image 80
Alexander Fasching Avatar answered Aug 16 '26 20:08

Alexander Fasching