I am trying to mock an external API using the responses library. I want to check I've passed my params correctly in my request, so I am using this minimum working example from the responses docs:
import responses
import requests
@responses.activate
def test_request_params():
responses.add(
method=responses.GET,
url="http://example.com?hello=world",
body="test",
match_querystring=False,
)
resp = requests.get('http://example.com', params={"hello": "world"})
assert responses.calls[0].request.params == {"hello": "world"}
The problem is, this breaks as soon as I replace http://example.com
with a URL that resembles an API endpoint:
@responses.activate
def test_request_params():
responses.add(
method=responses.GET,
url="http://example.com/api/endpoint?hello=world",
body="test",
match_querystring=False,
)
resp = requests.get('http://example.com/api/endpoint', params={"hello": "world"})
assert responses.calls[0].request.params == {"hello": "world"}
Now responses has added part of the URL to the first query param:
> assert responses.calls[0].request.params == {"hello": "world"}
E AssertionError: assert {'/api/endpoint?hello': 'world'} == {'hello': 'world'}
Am I missing something?
You can pass a regex as the url argument, which ignores parameters:
@responses.activate
def test_request_params():
url = r"http://example.com/api/endpoint"
params = {"hello": "world", "a": "b"}
# regex that matches the url and ignores anything that comes after
rx = re.compile(rf"{url}*")
responses.add(method=responses.GET, url=rx)
response = requests.get(url, params=params)
assert responses.calls[-1].request.params == params
url_path, *queries = responses.calls[-1].request.url.split("?")
assert url_path == url