getsentry / responses

A utility for mocking out the Python Requests library.
Apache License 2.0
4.14k stars 354 forks source link

`assert_all_requests_are_fired` does not work correctly. #627

Closed antondeliverect closed 1 year ago

antondeliverect commented 1 year ago

Describe the bug

Originally i wanted to make assert_all_requests_are_fired to work globally(it didn't work unfortunatelly._.) via fixture, but when i spend some time on it I've noticed that this param does not work consistently.

Additional context

the fixture i'm referring to is

@pytest.fixture(autouse=True)
def _allRequestsFired():
    responses.mock.assert_all_requests_are_fired = True

and all possible variations of it, as well as declaring responses.mock.assert_all_requests_are_fired = True in the test-file right after import responses.

Related issue would be https://github.com/getsentry/responses/issues/600

Version of responses

0.22

Steps to Reproduce

@responses.activate(assert_all_requests_are_fired=False)
def test_my():
    # Register mocks
    responses.get("http://lol.com")

    # Trigger method
    myCall()

def myCall():
    import requests
    requests.get("http://google.com")

Expected Result

Since assert_all_requests_are_fired is set to False, my test should pass.

Actual Result

it's not passing:

E           requests.exceptions.ConnectionError: Connection refused by Responses - the call doesn't match any registered mock.
E           
E           Request: 
E           - GET http://google.com/
E           
E           Available matches:
E           - GET http://lol.com/ URL does not match
beliaev-maksim commented 1 year ago

as per my comment https://github.com/getsentry/responses/issues/600#issuecomment-1447824807 have you tried latest master?

we should have fixed it in: https://github.com/getsentry/responses/pull/622

antondeliverect commented 1 year ago

@beliaev-maksim yes Sir.

i've pulled latest master via git clone git@github.com:getsentry/responses.git, uninstalled existing responses via pip3 uninstall responses, then created test_my.py in responses/ dir and executed it - it still does not work.

copy-paste from my terminal:

anton-m1:responses git:(master) ✗ anton$ python3 test_my.py
Traceback (most recent call last):
  ....
  File "/Users/anton/.pyenv/versions/3.10.9/lib/python3.10/site-packages/requests/api.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "/Users/anton/.pyenv/versions/3.10.9/lib/python3.10/site-packages/requests/api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "/Users/anton/.pyenv/versions/3.10.9/lib/python3.10/site-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/anton/.pyenv/versions/3.10.9/lib/python3.10/site-packages/requests/sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "/Users/anton/projects/.../responses/responses/__init__.py", line 1103, in unbound_on_send
    return self._on_request(adapter, request, *a, **kwargs)
  File "/Users/anton/projects/.../responses/responses/__init__.py", line 1045, in _on_request
    raise response
requests.exceptions.ConnectionError: Connection refused by Responses - the call doesn't match any registered mock.

Request:
- GET http://google.com/

Available matches:
- GET http://lol.com/ URL does not match

anton-m1:responses git:(master) ✗ anton$ cat test_my.py

import responses

@responses.activate(assert_all_requests_are_fired=False)
def test_my():
    # Register mocks
    responses.get("http://lol.com")

    # Trigger method
    myCall()

def myCall():
    import requests
    requests.get("http://google.com")

test_my()

anton-m1:responses git:(master) ✗ anton$
beliaev-maksim commented 1 year ago

sorry, I was not careful reading. So, I think you confuse how the feature should work

in your case you have a request that does not match any registered response, thus, you get an error. assert_all_requests_are_fired will check that all the registered responses were called, in your case if you do

@responses.activate(assert_all_requests_are_fired=False)
def test_my():
    # Register mocks
    responses.get("http://lol.com")
    responses.get("http://google.com")

    # Trigger method
    myCall()

def myCall():
    import requests
    requests.get("http://google.com")

but this one should fail:

@responses.activate(assert_all_requests_are_fired=True)
def test_my():
    # Register mocks
    responses.get("http://lol.com")
    responses.get("http://google.com")

    # Trigger method
    myCall()

def myCall():
    import requests
    requests.get("http://google.com")
antondeliverect commented 1 year ago

Oh, i see._. By any chance, do you know there's a flag to fail the test in case if I've registered the mock of "xxx.com" and my code executed unregistered request to "yyy.com"?

beliaev-maksim commented 1 year ago

you do not need a flag, it will fail automatically.

more tricky scenario when you have both registered, but you expect xxx.com instead of yyy.com here ordered registry will help you: https://github.com/getsentry/responses#ordered-registry