Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pytest does not raise HTTPError using mock.patch

My code is as following:

import pytest
import requests
from unittest import mock

@mock.patch('requests.get')
def test_verify(mock_request):
    mock_resp = mock.Mock()
    mock_resp.status_code = 404

    mock_request.return_value = mock_resp
    r = requests.get()

    with pytest.raises(requests.exceptions.HTTPError) as err_msg:
        r.raise_for_status()
    print(err_msg)

Since the status code of response is set to 404, I expect that a HTTPError will be raised. However, there is an error stating

Failed: DID NOT RAISE <class 'requests.exceptions.HTTPError'>

The output is as following:

======================================== test session starts ======================================== platform darwin -- Python 3.6.4, pytest-3.7.0, py-1.5.2, pluggy-0.7.1 rootdir: /Users/michael/Code/youtube-data-api, inifile: plugins: requests-mock-1.5.2 collected 1 item

temp_test.py F
[100%]

============================================= FAILURES ============================================== ____________________________________________ test_verify ____________________________________________

mock_request =

@mock.patch('requests.get')
def test_verify(mock_request):
    mock_resp = mock.Mock()
    mock_resp.status_code = 404

    mock_request.return_value = mock_resp
    r = requests.get()
    #print(r.status_code)

    with pytest.raises(requests.exceptions.HTTPError) as err_msg:
       r.raise_for_status() E           Failed: DID NOT RAISE <class 'requests.exceptions.HTTPError'>

temp_test.py:15: Failed ===================================== 1 failed in 0.12 seconds ======================================

terminal output: terminal output

like image 927
Michael Fengyuan Liu Avatar asked Aug 01 '18 17:08

Michael Fengyuan Liu


People also ask

What is mock in pytest?

The definition of mock in Merriam-Webster to imitate (someone or something) closely : MIMIC e.g. a mockingbird was mocking a cardinal In Python, you use mocks to replace objects for testing purposes. In the next section, I am going to show you how to mock in pytest.

What is the Mocker fixture in pytest-mock?

The mocker fixture is the interface in pytest-mock that gives us MagicMock. Before I go into the recipes, I want to tell you about the thing that confused me the most about Python mocks: where do I apply the mocks? In general, when you mock an object, you want to mock where the object is imported into not where the object is imported from.

What is the difference between raise_for_status () and mockmock_resp?

mock_resp is a mock.Mock () object. Calling raise_for_status () is just going to return another Mock (). You'll need to use a response that preserves the original raise_for_status ().

How to enable failfast on nosetest in Python?

-x (or --stop) (for nosetest): for enabling failfast on nosetest For a list of all the command-line options, use -h (or --help) option: The mock is a Python library to create mock objects, which helps us in replacing parts of your system under test with mock objects and set assertions about how they have been used.


1 Answers

mock_resp is a mock.Mock() object. Calling raise_for_status() is just going to return another Mock().

You'll need to use a response that preserves the original raise_for_status(). Try this:

import pytest
import requests
from unittest import mock

@mock.patch('requests.get')
def test_verify(mock_request):
    mock_resp = requests.models.Response()
    mock_resp.status_code = 404
    mock_request.return_value = mock_resp
    res = requests.get()
    with pytest.raises(requests.exceptions.HTTPError) as err_msg:
        res.raise_for_status()
    print(err_msg)
like image 173
wholevinski Avatar answered Oct 23 '22 07:10

wholevinski