Dinero
Dinero

Reputation: 1160

Mock a api response

Background

I have a function called submit_health which is responsible for doing a POST request on some data we pass. The expected output is always in the following form :

{
    "errors": [],
    "warnings": [],
    "success": true
} 

The only difference is that in some cases if we send invalid data the "success": false is possible and of course "errors" and "warnings" would have the appropriate text stating why there was no successful post request.

Code

   def submit_health(health_data):
        return _post_json("health-single", health_data)


def _post_json(resource: str, data: Dict) -> PostResponse:
    json_data = json.dumps(data, default=json_encoding_decimal_default)
    response = request_session_with_retry().post(
        f"{SITE_API_ROOT}/v3/{resource}",
        auth=("", SITE_API_V3_KEY),
        data=json_data,
        headers={"Content-Type": "application/json", "User-Agent": USER_AGENT},
    )
    response.raise_for_status()
    try:
        return json.loads(response.text)
    except Exception:
        return None

ISSUE

I am attempting to test the submit_health function using pytest. I am not concerned with the implementation of the API as a different part of the code is dealing with that test. I am only concerned with testing it with the expected output which is

{
    "errors": [],
    "warnings": [],
    "success": true
} 

My question is how would I mock this response? I would love for any suggestions. I read a little bit about monkey patching but I am not quite sure yet how to mock a response. I would love for some guidance.

Upvotes: 1

Views: 1230

Answers (1)

Lucas Godoy
Lucas Godoy

Reputation: 812

Assuming your function is located in health.py module I would create a test_health.py module with code:

from unittest.mock import Mock, patch

from health import submit_health


@patch("health.request_session_with_retry")
def test_submit_health(request_mock):
    response_mock = Mock(text='{"errors": [], "warnings": [], "success": true}')
    request_mock.return_value.get.return_value = response_mock

    result = submit_health({"foo": "bar"})

    assert result == {"errors": [], "warnings": [], "success": True}
  1. @patch passes the patched function as an argument which I named request_mock
  2. We need to mas what that mock is going to return when request_session_with_retry.get is called

Upvotes: 2

Related Questions