I'm testing for a specific response code and want to mock out a test case when the code is something different, like unauthorized 401
. I'm using the Python 3.7 http.client library and pytest
So far I tried to use the @patch
decorator and call a function with side_effect
to trigger the exception
my test case:
from unittest import mock
from application import shorten_url
def mock_status(url):
raise ConnectionError
@patch("application.shorten_url", side_effect=mock_status)
def test_bitly(client):
with pytest.raises(ConnectionError) as e:
shorten_url("something")
my code:
def shorten_url(url):
conn = http.client.HTTPSConnection("api-ssl.bitly.com", timeout=2)
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer abcd",
}
payload = json.dumps({"long_url": url})
conn.request("POST", "/v4/shorten", payload, headers)
res = conn.getresponse()
if not res.status == 201:
raise ConnectionError
data = json.loads(res.read())
return data["link"]
I don't really understand how to raise this exception correctly using mock
and side_effect
.
A friend helped me with the issue, this seems to work (it's still very confusing for me):
from unittest.mock import patch, MagicMock
@patch("http.client.HTTPSConnection")
@patch("http.client.HTTPResponse")
def test_bitly(mock_conn, mock_res):
mock_res.status = 400
mock_conn.getresponse = MagicMock(return_value=mock_res)
with pytest.raises(ConnectionError):
shorten_url("fake-url")
I think this answer is easier to understand. First I created a fake http connection and response:
class FakeHTTPConnection:
def __init__(self, status):
self.status = status
def request(self, *args):
# If you need to do any logic to change what is returned, you can do it in this class
pass
def getresponse(self):
return FakeHTTPResponse(self.status)
class FakeHTTPResponse:
def __init__(self, status):
self.status = status
Then in my test class, I overrode http.client.HTTPConnection
to create my instance instead.
class TestFoo(unittest.TestCase):
@patch('http.client.HTTPConnection', new=MagicMock(return_value=FakeHTTPConnection(200)))
def test_foo_success(self):
conn = http.client.HTTPConnection("127.0.0.1")
conn.request("GET", "/endpoint")
response = conn.getresponse()
success = response.status == http.HTTPStatus.OK
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.