I'm trying to set-up a fixture that will mock some responses for https://github.com/influxdata/influxdb-python and then I want to use the same fixture in some tests to add additional matchers.
If the API had suited what I was attempting to do, I could've written my fixture like this,
# requests_mock is already a pytest fixture according to https://requests-mock.readthedocs.io/en/latest/pytest.html
import requests_mock as req_mock
@pytest.fixture
def requests_mock_context():
with req_mock.Mocker(real_http=True) as m:
base_url = "http://localhost:8086"
# Mock ping
# curl -sL -I localhost:8086/ping -> HTTP 204, see also
#
# https://github.com/influxdata/influxdb-python/blob/master/influxdb/tests/client_test.py#L660
m.get(f"{base_url}/ping", status_code=204, headers={'X-Influxdb-Version': '1.2.3'})
# Mock create_database, see
#
# https://github.com/influxdata/influxdb-python/blob/master/influxdb/tests/client_test.py#L672
#
# to discover that this is the expected result
empty_positive_result: dict[str, list[dict[str, str]]] = {"results": [{}]}
is_create_db_request = lambda request: "CREATE+DATABASE" in request.url
m.post(f"{base_url}/query", additional_matcher=is_create_db_request, json=empty_positive_result)
is_show_measurements_request = lambda request: "SHOW+MEASUREMENTS" in request.url
m.get(
f"{base_url}/query",
additional_matcher=is_show_measurements_request,
json=empty_positive_result,
)
is_show_tag_keys_request = lambda request: "SHOW+TAG+KEYS" in request.url
m.get(
f"{base_url}/query", additional_matcher=is_show_tag_keys_request, json=show_tag_keys_response
) # `show_tag_keys_response` is a fixture of its own
yield m
and used it in my code like this,
def test_stuff(request_mock_context):
example_response = (
'{"results": [{"series": [{"measurement": "sdfsdfsdf", '
'"columns": ["time", "y"], "values": '
'[["2009-11-10T22:00:00Z", 0.64]]},{"measurement": "sdfsdfsdf", '
'"columns": ["time", "y"], "values": '
'[["2009-11-10T23:00:00Z", 0.65]]}]}]}'
)
is_select_query = lambda request: "SELECT" in request.url
requests_mock_context.get(f"{influxdb_url}/query", additional_matcher=is_select_query, text=example_response)
Unfortunately, only the latest registered matcher on the URL will apply which isn't unreasonable.
One workaround I see is creating a fixture for the matcher instead - is there some other way? And if there is, is there some reasonable way to parameter-pass show_tag_keys_response
back to the fixture as that can vary in the tests but otherwise the set-up is shared across many tests that currently set this up on their own.