I'm trying to understand the example provided here and emulate it to work for the post method instead of get method.
All works well when I'm testing for response.status_code == 200. How do I test for more than one response status codes without repeating the code (like in here?
I understand that one needs to use fixtures, how do I leverage them?
This is where I'm up to now.
app.py
from typing import Dict, Union
from urllib.error import HTTPError
import requests
import structlog
logger = structlog.get_logger()
def get_access_token(
url: str, client_id: str, client_secret: str, grant_type: str
) -> Union[Dict[str, Union[str, int]], None]:
try:
r = requests.post(
url,
data={"grant_type": grant_type},
auth=(client_id, client_secret),
verify=True,
)
logger.info("Fetching token status code", status_code=r.status_code)
except HTTPError as http_err:
logger.error("HTTP error occurred", http_error=str(http_err))
except Exception as err:
logger.error("Other error occurred", exception=str(err))
else:
# The token expires in 10800 seconds
return r.json()
test_app.py
# contents of test_app.py, a simple test for our API retrieval
from typing import Dict, Union
import pytest
import requests
from app import get_access_token
# custom class to be the mock return value of requests.post()
class MockResponse:
status_code = 200
raise_for_status = None
@staticmethod
def json() -> Dict[str, Union[str, int]]:
return {
'access_token': 'fake-access-token',
'token_type': 'fake-token-type',
'expires_in': 10800,
}
@pytest.fixture
def mock_response(monkeypatch):
"""Requests.post() mocked to return json."""
def mock_post(*args, **kwargs):
return MockResponse()
monkeypatch.setattr(requests, "post", mock_post)
# notice our test uses the custom fixture instead of monkeypatch directly
def test_get_access_token_success(mock_response) -> None:
result = get_access_token(
url="https://fakeurl",
client_id="fake-client-id",
client_secret="fake-client-secret",
grant_type="fake-grant-type",
)
assert result['access_token'] == "fake-access-token"
assert result['token_type'] == "fake-token-type"
rewrote app.py after @gold_cy's suggestion
from typing import Dict, Union
import requests
import structlog
logger = structlog.get_logger()
def get_access_token(
url: str,
client_id: str,
client_secret: str,
grant_type: str = 'client_credentials',
) -> Dict[str, Union[str, int]]:
try:
r = requests.post(
url,
data={"grant_type": grant_type},
auth=(client_id, client_secret),
verify=True,
)
logger.info("Fetching token status code", status_code=r.status_code)
r.raise_for_status()
if r.status_code == 200:
# FIXME: The token expires in 10800 seconds
return r.json()
except requests.exceptions.HTTPError as err:
logger.error("HTTP error", request=err.response.text)
raise requests.HTTPError(err)