0

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.

Filip Allberg
  • 3,941
  • 3
  • 20
  • 37
  • you probably need --> https://requests-mock.readthedocs.io/en/latest/matching.html#custom-matching – gold_cy Apr 02 '23 at 10:47

0 Answers0