Skip to content
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

No longer works with starlette/fastapi TestClient #165

Open
sscherfke opened this issue Oct 24, 2024 · 2 comments
Open

No longer works with starlette/fastapi TestClient #165

sscherfke opened this issue Oct 24, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@sscherfke
Copy link

Follow-up of #144 (comment)


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

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.

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

My current workaround is this fixture:

@pytest.fixture
def httpx_testclient_mock(monkeypatch: pytest.MonkeyPatch) -> HTTPXMock:
    # This fixture is a workaound for
    # https://github.com/Colin-b/pytest_httpx/issues/144
    mock = HTTPXMock()

    def mocked_handle_request(
        transport: httpx.HTTPTransport, request: httpx.Request
    ) -> httpx.Response:
        return mock._handle_request(transport, request)  # noqa: SLF001

    monkeypatch.setattr(
        starlette.testclient._TestClientTransport,  # noqa: SLF001
        "handle_request",
        mocked_handle_request,
    )

    return mock
@Colin-b
Copy link
Owner

Colin-b commented Oct 25, 2024

Hello @sscherfke

This usage was not part of the non regression suite, and was never documented.
However I agree it would be a good addition if most parameters still make sense.

I will have a look at it and see what can be done here.

Thanks for reporting

@sscherfke
Copy link
Author

Thx, let me know if I can help you with anything <3

@Colin-b Colin-b added the enhancement New feature or request label Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants