Home > Blockchain >  how to mock the response from a library api in pytest
how to mock the response from a library api in pytest

Time:06-26

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============================================================
  • Related