Writing an pytest for a function that is making api call using an installed package. How do you mock the response from the api response?
This is how the function looks like
import hubspot
from pprint import pprint
from hubspot. import ApiException
def get_clicked_events():
client = hubspot.Client.create(api_key="YOUR_HUBSPOT_API_KEY")
try:
api_response = client.events_api.get_page(limit=100, event_type="clicked")
pprint(api_response)
return api_response
except ApiException as e:
print("Exception when calling events_api->get_page: %s\n" % e)
CodePudding user response:
Have a look at requests-mock. It provides a fixture requests_mock
that you can put in your test function. In the function, you mock the API call with requests_mock.get("https://api-url")
, and optionally add a response, status code, etc..
CodePudding user response:
In your case you need to mock the hubspot.Client
object and then mock the appropriate methods that are being called. Your function doesn't make sense just printing when there is an error, you should just let the error propagate up to the caller wherever that is coming from. I slightly modified your function to error out in order to show that and how to test both scenarios.
# src/get_events.py
from hubspot import Client
from hubspot.events.exceptions import ApiException
def get_clicked_events():
client = Client.create(api_key="YOUR_HUBSPOT_API_KEY")
try:
api_response = client.events.get_page(limit=100, event_type="clicked")
except ApiException:
raise
return api_response
from unittest.mock import patch
import pytest
from hubspot import Client
from hubspot.events.exceptions import ApiException
from src.get_events import get_clicked_events
def test_get_clicked_events_success():
with patch("src.get_events.Client", spec=Client) as mock_client:
mock_client.configure_mock(
**{
"create.return_value": mock_client,
"events.get_page.return_value": "fizz"
}
)
events = get_clicked_events()
assert events == "fizz"
def test_get_clicked_events_fail():
err_msg = "Failed to get events!"
with patch("src.get_events.Client", spec=Client) as mock_client:
mock_client.configure_mock(
**{
"create.return_value": mock_client,
"events.get_page.side_effect": ApiException(err_msg)
}
)
with pytest.raises(ApiException) as err:
get_clicked_events()
assert err_msg == err.value
Then when running from the root of the repository you can see both tests pass.
platform darwin -- Python 3.8.9, pytest-7.0.1, pluggy-1.0.0
cachedir: .pytest_cache
rootdir: ***
plugins: mock-3.7.0
collected 2 items
tests/test_script.py::test_get_clicked_events_success PASSED [ 50%]
tests/test_script.py::test_get_clicked_events_fail PASSED [100%]
=========================================================== 2 passed============================================================