首页 > 解决方案 > 如何在 Python 3 中模拟连接和超时错误?

问题描述

我是 Python 的新手。我试图在我的单元测试中模拟异常并测试我的代码块;但是异常消息始终为空。这是下面推荐的模拟异常的方法吗?另外如何确保异常消息不为空?

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)

标签: python-3.xmockingpytest

解决方案


长话短说:你没有收到消息,因为你没有指定一个。

您可能想要检查'Failure: '而不是'Error: ',因为这是您为原始异常消息添加前缀的内容。这可能是您的代码中的真正问题,而不是您在测试中引发的异常的空字符串表示形式。

为什么是str(err)空的?

看一下类层次结构:

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

IOError__str__如果向构造函数提供了多个参数,则覆盖,否则BaseException应用以下行为:

如果在此类的实例上调用 str(),则返回实例的参数表示形式,或者在没有参数时返回空字符串。 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'

最后一个例子是IOError异常定义的行为。


推荐阅读