pytest, raise_for_status с ошибкой: НЕ ВЫЗЫВАЛ запросы

#python #http #python-requests #pytest

#python #http #python-запросы #pytest

Вопрос:

Это для документирования чего-то, на что я натыкался долгое время.

Это не работает. try/except/else Предложение проглотит исключение, сгенерированное r.raise_for_status() .

 import requests
from requests.exceptions import HTTPError
import pytest
import logging

def fetch(url):
    """HTTP request"""
    try:
        r = requests.get(url)
        r.raise_for_status()
    except HTTPError as err:
        logging.warning(f'Fetching url failed {err}')
    else:
        print(r.data)


def test_fetch(mocker):
    """Test."""
    mock_response = mocker.Mock(requests.Response)
    expected_exc = HTTPError()
    mock_response.raise_for_status.side_effect = expected_exc
    mocker.patch.object(requests, 'get')
    requests.get.return_value = mock_response
    r = fetch('http://httpbin.org/status/400')
    with pytest.raises(HTTPError) as err_msg:
        r.raise_for_status()
  

Сообщение об ошибке, полученное от pytest, является

 
example.py F                                                                                                                      [100%]

====================================================================== FAILURES =======================================================================
_____________________________________________________________________ test_fetch ______________________________________________________________________

mocker = <pytest_mock.plugin.MockFixture object at 0x1095cd100>

    def test_fetch(mocker):
        """Test."""
        mock_response = mocker.Mock(requests.Response)
        expected_exc = HTTPError()
        mock_response.raise_for_status.side_effect = expected_exc
        mocker.patch.object(requests, 'get')
        requests.get.return_value = mock_response
        with pytest.raises(HTTPError) as err_msg:
>           fetch('http://httpbin.org/status/400')
E           Failed: DID NOT RAISE <class 'requests.exceptions.HTTPError'>

example.py:25: Failed
------------------------------------------------------------------ Captured log call ------------------------------------------------------------------
WARNING  root:example.py:12 Fetching url failed
=============================================================== short test summary info ===============================================================
FAILED example.py::test_fetch - Failed: DID NOT RAISE <class 'requests.exceptions.HTTPError'>
================================================================== 1 failed in 0.20s ==================================================================

  

Я дал ответ ниже.

Ответ №1:

Если вы действительно чувствуете, что вам нужно протестировать raise_for_status здесь. Необходимо снова вызвать исключение.

 import requests
from requests.exceptions import HTTPError
import pytest
import logging

def fetch(url):
    """HTTP request"""
    try:
        r = requests.get(url)
        r.raise_for_status()
    except HTTPError as err:
        logging.warning(f'Fetching url failed {err}')
        # HERE raise again.
        raise
    else:
        print(r.data)


def test_fetch(mocker):
    """Test."""
    mock_response = mocker.Mock(requests.Response)
    expected_exc = HTTPError()
    mock_response.raise_for_status.side_effect = expected_exc
    mocker.patch.object(requests, 'get')
    requests.get.return_value = mock_response
    with pytest.raises(HTTPError) as err_msg:
        fetch('http://httpbin.org/status/400')
  

Ответ №2:

Вместо того, чтобы просто выполнять вход в блок except, также поднимите.

 except HTTPError as err:
    logging.warning(f'Fetching url failed {err}')
    raise
  

Потому что: pytest.raises ищет условия повышения, а не исключения.