diff --git a/httpx/_transports/mock.py b/httpx/_transports/mock.py index 8c418f59..9fd5ec68 100644 --- a/httpx/_transports/mock.py +++ b/httpx/_transports/mock.py @@ -1,5 +1,6 @@ from __future__ import annotations +import datetime import typing from .._models import Request, Response @@ -24,6 +25,7 @@ class MockTransport(AsyncBaseTransport, BaseTransport): response = self.handler(request) if not isinstance(response, Response): # pragma: no cover raise TypeError("Cannot use an async handler in a sync Client") + response.elapsed = datetime.timedelta() return response async def handle_async_request( @@ -40,4 +42,5 @@ class MockTransport(AsyncBaseTransport, BaseTransport): if not isinstance(response, Response): response = await response + response.elapsed = datetime.timedelta() return response diff --git a/tests/client/test_client.py b/tests/client/test_client.py index 65783901..535c741f 100644 --- a/tests/client/test_client.py +++ b/tests/client/test_client.py @@ -460,3 +460,40 @@ def test_client_decode_text_using_explicit_encoding(): assert response.reason_phrase == "OK" assert response.encoding == "ISO-8859-1" assert response.text == text + + +def test_mock_transport_elapsed(): + """Test that MockTransport sets the elapsed property. + + Regression test for https://github.com/encode/httpx/issues/3712 + """ + def handler(request): + return httpx.Response(200, json={"text": "Hello, world!"}) + + transport = httpx.MockTransport(handler) + with httpx.Client(transport=transport) as client: + response = client.get("http://www.example.com") + assert response.status_code == 200 + # MockTransport should set elapsed to timedelta(0) + assert response.elapsed == timedelta(0) + # Accessing elapsed should not raise RuntimeError + assert isinstance(response.elapsed, timedelta) + + +@pytest.mark.anyio +async def test_async_mock_transport_elapsed(): + """Test that MockTransport sets the elapsed property for async requests. + + Regression test for https://github.com/encode/httpx/issues/3712 + """ + def handler(request): + return httpx.Response(200, json={"text": "Hello, world!"}) + + transport = httpx.MockTransport(handler) + async with httpx.AsyncClient(transport=transport) as client: + response = await client.get("http://www.example.com") + assert response.status_code == 200 + # MockTransport should set elapsed to timedelta(0) + assert response.elapsed == timedelta(0) + # Accessing elapsed should not raise RuntimeError + assert isinstance(response.elapsed, timedelta)