1

* EDITED*

I would like to test what will happen if external API will return 500 status code.

main.py

@app.route("/<a>/<b>", methods=["GET"])
def repo_info(a: str, b: str) -> Union[Response, str]:
    info = some_func(a, b)
    result = create_result_dict(some_func)
    return Response(
        response=json.dumps(result, ensure_ascii=False),
        status=200,
        mimetype="application/json",

@app.errorhandler(500)
def server_error(e):
    logging.exception(f"An error occurred during a request: {e}.")
    return Response(
        response="An internal error occurred. See logs for full stacktrace.",
        status=500,
    )
my_module.py

def some_func(a: str, b: str) -> Dict[str, str]:
    return json.loads(
        (requests.get(f"https://api.github.com/repos/{a}/{b}")).text
    )

I tried around this code but feel like headless chicken:

from flask import Response
import pytest
import requests

from unittest.mock import patch
from requests.exceptions import HTTPError

@patch.object(my_module, "some_func")
def test_some_func(mocked):
    mocked.return_value = HTTPError()
    result = my_module.some_func()
    with pytest.raises(HTTPError):
        result == mocked 

Also HTTPError doesn't takes arguments, how can I pass information, that I would like 500 status code?

Marta
  • 95
  • 3
  • 9
  • Please include code of `my_module.some_func` because this determines what to patch and how. – tmt Oct 23 '19 at 07:01

1 Answers1

1

The first issue is that to get HTTPError exception you need to tell requests to raise it with raise_for_status():

# my_module.py

import json
import requests
from typing import Dict

def some_func(a: str, b: str) -> Dict[str, str]:
    result = requests.get(f"https://api.github.com/repos/{a}/{b}")
    result.raise_for_status()

    return json.loads(result.text)

The second issue is that to mock it, you only want to mock requests (to set the conditions as well as to avoid making real calls to the API) because otherwise you do want to call some_func(). After all, that's the idea of testing it. You can patch the objects the way you tried but I'd suggest that you rather install requests-mock:

# test.py

import pytest
import requests_mock
from requests.exceptions import HTTPError
from my_module import some_func

def test_some_func():
    with requests_mock.mock() as m:
        m.get(requests_mock.ANY, status_code=500, text='some error')

        with pytest.raises(HTTPError):
            # You cannot make any assertion on the result
            # because some_func raises an exception and
            # wouldn't return anything
            some_func(a="a", b="b")
tmt
  • 7,611
  • 4
  • 32
  • 46