getsentry / responses

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

Response count not reset when defining Response outside of test function #687

Closed svleeuwen closed 7 months ago

svleeuwen commented 8 months ago

I prefer to define responses in a separate module outside of test functions. But then the response.call_count is not reset when the test ends.

Adding copy.copy does fix the issue, but maybe this can be circumvented so I don't have to use that?

Example:

import requests
import responses

url = "https://example.com"
response_200_ok = responses.Response("GET", url)

@responses.activate()
def test_one():
    responses.add(response_200_ok)
    requests.get(url)
    assert response_200_ok.call_count == 1

@responses.activate()
def test_two():
    responses.add(response_200_ok)
    requests.get(url)
    assert response_200_ok.call_count == 1  # this fails since the call count is 2

Working example:

import copy
import requests
import responses

url = "https://example.com"
response_200_ok = responses.Response("GET", url)

@responses.activate()
def test_one():
    r = responses.add(copy.copy(response_200_ok))
    requests.get(url)
    assert r.call_count == 1

@responses.activate()
def test_two():
    r = responses.add(copy.copy(response_200_ok))
    requests.get(url)
    assert r.call_count == 1
beliaev-maksim commented 8 months ago

I would say that is the desired behavior

you do not need to copy the object, you can set up test class and on teardown or setup of the method initialize the response or reset call count

svleeuwen commented 8 months ago

Do you mean by doing something like this?

@pytest.fixture(autouse=True)
def reset_response_mocks():
    yield
    response_200_ok.call_count = 0
beliaev-maksim commented 8 months ago

that is a fixture which technically will work, but I would rather use class with setup or teardown method

https://docs.pytest.org/en/7.1.x/how-to/xunit_setup.html#method-and-function-level-setup-teardown

svleeuwen commented 8 months ago

Got it.

But my main question was, the only way to reset the call count would be to set the call_count attribute on every Response instance?

beliaev-maksim commented 8 months ago

or on every test you initialize a new object

class Test:
    def setup_method(self):
         self.response_200_ok = responses.Response("GET", url)
    def test1(self):
         r = responses.add(self.response_200_ok )

smth like this

svleeuwen commented 8 months ago

But my goal is to reuse the same responses in multiple tests.

That's why I started with:

I prefer to define responses in a separate module outside of test functions.

beliaev-maksim commented 8 months ago

then just reset the call counter. but this is until #664 is merged, then you have to clean up the list