Colin-b / pytest_httpx

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

Custom Async Client's Transport is not used #120

Closed Tomas2D closed 11 months ago

Tomas2D commented 1 year ago

Hello 👋🏻 Thanks for this great library!

I've recently found an issue where I found the Async Client's Transport is not used in tests. However, it should be.

Example of using custom transport:

import asyncio
from httpx import AsyncClient
from http_utils import AsyncRetryTransport

async def run():
    client = AsyncClient(
        transport=AsyncRetryTransport(retries=1)
    )
    result = await client.post(...)
    return result.json()

if __name__ == '__main__':
    asyncio.run(run())

When I send a request which fails, then it's automatically repeated. This does not happen during testing.

import httpx
import pytest
from pytest_httpx import HTTPXMock
from contextlib import nullcontext as does_not_raise

from main import run

@pytest.mark.asyncio
async def test_main(httpx_mock: HTTPXMock):
    httpx_mock.add_response(method="POST", status_code=httpx.codes.TOO_MANY_REQUESTS, json={})
    httpx_mock.add_response(method="POST", status_code=httpx.codes.OK, json={
        "id": 1,
    })

    # It should not throw, because the second request shall pass
    with does_not_raise():
        response = await run()
        assert response is not None

Example Repository: https://github.com/Tomas2D/httpx-pytest-transport-bug

Colin-b commented 1 year ago

Hello,

Thanks for reporting, if you mind pointing me to the source code of this transport I could check if there was a way to achieve this. In any case that is indeed a limitation of the current mock and I will not be able to have a look at it before a few weeks unfortunately.

Best Regards

Tomas2D commented 1 year ago

Here it is: https://github.com/Tomas2D/httpx-pytest-transport-bug/blob/main/http_utils.py

The repo is really small; only the necessary parts are in it. Just a few files. Basically, the handle_async_request in my transport is not called, but it should be.

Colin-b commented 1 year ago

Mocking the handle_async_request instead of the class should do the trick indeed. If you don't mind waiting I should be able to work on this in a few weeks :)

Tomas2D commented 1 year ago

Not sure about that. The library does not use the actual transport's handle_async_request. It will be more complex. I am looking forward to your approach.

Tomas2D commented 11 months ago

Any update? :)

Colin-b commented 11 months ago

Not sure about that. The library does not use the actual transport's handle_async_request. It will be more complex. I am looking forward to your approach.

The linked sample you provided is using handle_async_request and this is indeed an issue. If the fix (version 0.27.0) is not appropriate for your use case, feel free to open another issue with more details on the custom transport (how the actual http call is done)

Tomas2D commented 11 months ago

From quick testing in the provided repository, it works as expected after the update. I will let you know if I encounter a problem with our more extensive project. Thank you, I appreciate your work.