-
-
Notifications
You must be signed in to change notification settings - Fork 954
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use TestClient with requests_mock? #818
Comments
I'm afraid I'm not able to help out with this - you'll need to dig into it yourself. |
# conftest.py
@fixture
def mock_requests_get(monkeypatch):
def wrapped(return_value=None, side_effect=None):
def what_to_return(*args, **kwargs):
if side_effect:
raise side_effect # pragma: nocover
return return_value
monkeypatch.setattr("requests.get", what_to_return)
return wrapped # test_something.py
def test_something_useful(mock_requests_get):
mock_requests_get(MyFakeResponse())
# .... Real examples are here: https://github.com/em92/quakelive-local-ratings/blob/7e1fd1432d36dd4912ce3d8db4efee1168cdb05e/tests/test_balance_api.py#L191-L223 |
Thanks for the response @em92 , but this heavy mocking is exactly what I would like to avoid. Not only this would have less testing value but will require heavy refactors on all tests. Is there really no way to make starlette's |
Presumably requests_mock has some way of specifying which session instance you want to mock. (So create a global session instance for your endpoints to use and only attach the mocking to that instance.) |
Nowadays it's easy to do: requests_mock supports an argument |
@buotex I was able to getting the following working thanks with requests_mock.Mocker(real_http=True) as m:
m.post(
"http://localhost:3001/services/oauth2/token",
json={"access_token": "a_random_token"},
)
response = client.post("/order/", json=data) Where the client is a |
It works fine for me (on FastAPI) even without conftest.py @pytest.fixture(scope='session')
def client():
with requests_mock.Mocker() as rm:
rm.get('https://domain.com/path', json={})
with TestClient(app) as c:
yield c test_app.py def test_route(client):
res = client.get('/route')
assert res.status_code == 200 Application code that uses |
This doesn't seem to work anymore due to the TestClient using a
|
I got it working by adding @pytest.fixture(scope="module")
def module_client():
with TestClient(app) as c:
yield c
@pytest.fixture
def client(module_client, requests_mock):
test_app_base_url_prefix_regex = re.compile(fr"{re.escape(module_client.base_url)}(/.*)?")
requests_mock.register_uri(ANY, test_app_base_url_prefix_regex, real_http=True)
return module_client |
For anyone ending up here through upgrading Starlette to 0.21 or FastAPI >= 0.87 after #1376 replacing Requests for HTTPX in the TestClient, and getting mocking failures along the lines of
There's an easy way of telling @pytest.fixture()
def non_mocked_hosts() -> list:
return ["testserver"] I know this thread is 3 years old 😄 sorry for the bump |
Suppose I have a route in my API that creates an http request to an external resource using
requests
package. When creating a starletteTestClient
, it creates four adapters for ws, wss, http and https, so that it can handle all requests to the API. This is problematic since if I want to mock a route withrequests_mock.Mocker()
forrequests
to use, all the adapters created byTestClient
get overwritten and do not get matched anymore resulting inNoMockAddressError
.I want to create a test with a mocked response for the address I use in my tested API route, so that the route actually sends the request, gets the response and returns it. How do I go about using
TestClient
along withrequests_mock.Mocker
? Can I somehow extendTestClient
'shttp
matchers or should I do it differently? Below is an example of a test that is not working for me:queue.py
conftest.py
test_queue.py
The text was updated successfully, but these errors were encountered: