I'm using python responses module to mock API response in my tests. The problem is that after the url is registered responses.add() it can be called only once with requests.get(), subsequent calls for the same URL raise an exception.
import requests
import responses
URL = 'http://localhost/abcd'
# Test method
@responses.activate
def get_url(url):
return requests.get(url)
# Set up URL mock
responses.add(responses.GET, URL, body="A B C D")
Now the first call works:
>>> print(get_url(URL)) # <Response [200]>
However the same call again fails:
>>> print(get_url(URL))
Traceback (most recent call last):
File "test-responses.py", line 19, in <module>
print(get_url(URL))
File "<string>", line 3, in wrapper
File "test-responses.py", line 10, in get_url
return requests.get(url)
File ".../site-packages/requests/api.py", line 75, in get
return request('get', url, params=params, **kwargs)
File ".../site-packages/requests/api.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File ".../site-packages/requests/sessions.py", line 533, in request
resp = self.send(prep, **send_kwargs)
File ".../site-packages/requests/sessions.py", line 646, in send
r = adapter.send(request, **kwargs)
File ".../site-packages/responses.py", line 674, in unbound_on_send
return self._on_request(adapter, request, *a, **kwargs)
File ".../site-packages/responses.py", line 654, in _on_request
raise response
requests.exceptions.ConnectionError: Connection refused by Responses - the call doesn't match any registered mock.
Request:
- GET http://localhost/abcd
Available matches:
>>>
Is there any way to make the mock URLs permanent and call them as many times as the tests need?
The problem with your original code is that get_url wrapped with decorator and it creates a new responses context every time when get_url is called, but response.add register url mock is registered only once - for the first response context.
@response.activate decorator intended to be used for test cases.
Here is correct way of using decorator that allows to make requests to same url.
@responses.activate
def test_function():
responses.add(responses.GET, URL, body="A B C D")
print(get_url(URL))
print(get_url(URL))
test_function()
Using responses.start() / responses.stop() allows to make many requests for the same URL.
import requests
import responses
URL = 'http://localhost/abcd'
def get_url(url):
return requests.get(url)
# Test method
responses.start()
# Set up URL mock
responses.add(responses.GET, URL, body="A B C D")
print(get_url(URL))
print(get_url(URL))
responses.stop()
For unit tests I'm using this mixing code .
BTW Latest responses version (0.12.0) has function assert_calls_count that allows to check the number of requests to url without exception.
assert responses.assert_call_count(URL, 1) is True
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With