Colin-b / pytest_httpx

pytest fixture to mock HTTPX
https://colin-b.github.io/pytest_httpx/
MIT License
363 stars 31 forks source link

The following responses are mocked but not requested #144

Closed jonathan-s closed 2 months ago

jonathan-s commented 7 months ago

Instead of showing an object that looks like the one below, it would be better to have an object that is human readable.

E           AssertionError: The following responses are mocked but not requested:
E             Match all requests
E           assert not [<pytest_httpx._httpx_mock._RequestMatcher object at 0x10e1f6a60>]
jonathan-s commented 7 months ago

Seems like this is possibly an edgecase when the url and everything is else is empty.

Colin-b commented 7 months ago

Hello @jonathan-s Can you provide a sample to reproduce? Thanks again

sscherfke commented 7 months ago

I am having a similar problem. The following example works with pytest-httpx 0.26 but fails with pytest-httpx 0.30:

import fastapi
import httpx
import pytest
import pytest_asyncio
import pytest_httpx

@pytest_asyncio.fixture
async def client() -> fastapi.FastAPI:
    app = fastapi.FastAPI()

    @app.get("/")
    def get() -> None:
        return None

    async with httpx.AsyncClient(
        transport=httpx.ASGITransport(app=app),
        base_url="http://test",
    ) as api_client:
        yield api_client

@pytest.mark.asyncio
async def test_ok(client: httpx.AsyncClient) -> None:
    response = await client.get("/")
    assert response.status_code == 200

@pytest.mark.asyncio
async def test_err(
    client: httpx.AsyncClient, httpx_mock: pytest_httpx.HTTPXMock
) -> None:
    httpx_mock.add_response(status_code=500, text="Internal Server Error")
    response = await client.get("/")
    assert response.status_code == 500

I think the reason is that both, the Starlette text client and pytest-httpx, try to modify the HTTPX transport.

sscherfke commented 7 months ago

httpx.ASGITransport inherits httpx.AsyncBaseTransport and pytest-httpx only mocks httpx.AsyncHTTPTransport.

I don't think it would be a good idea to mock the base transport, because its handle-Method is "abstract" and should remain so.

Maybe it should mock the asgi/wsgi transport in addition to the http transport or allow passing a list of transport classes to mock.

sscherfke commented 7 months ago

The Starlette test client inherts httpx.BaseTransport: https://github.com/encode/starlette/blob/master/starlette/testclient.py#L239

Colin-b commented 2 months ago

Hello @sscherfke , this does not seem to be related at all. Could you open an issue describing your need if any?

Colin-b commented 2 months ago

As for your issue @jonathan-s,

The display performed by pytest-httpx is:

AssertionError: The following responses are mocked but not requested:
E             Match all requests

The one from pytest is:

assert not [<pytest_httpx._httpx_mock._RequestMatcher object at 0x10e1f6a60>]

So this is the best we can do here, the error is indeed the one you described. You put a request matcher matching every incoming request while none was issued.

If you still feel like this is not clear enough feel free to reopen with a suggestion on what could be displayed for more clarity.

Thanks again