Skip to content

Commit 8473fd4

Browse files
karlwaldmanclaude
andcommitted
test(telemetry): drop respx so the new tests run on CI's dev extras (#105)
respx is not in the [dev] extra, so the new module failed to import on every matrix Python and collection errored. Mock at httpx.Client.request / httpx.AsyncClient.request instead, which is what the rest of tests/unit does. Same assertions, same red against pre-fix code (10 failed, 2 passed). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ao5paex73xXvuM424Libo
1 parent 235fb91 commit 8473fd4

1 file changed

Lines changed: 27 additions & 26 deletions

File tree

‎tests/unit/test_telemetry_lifecycle.py‎

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@
1111
4. a telemetry failure must never alter or fail a request result
1212
1313
No test here is ever allowed to make a real network call: every test replaces
14-
``oilpriceapi.telemetry.httpx.post`` with a local sink.
14+
``oilpriceapi.telemetry.httpx.post`` with a local sink, and the API calls are
15+
patched at ``httpx.Client.request`` / ``httpx.AsyncClient.request`` the way the
16+
rest of the unit suite does it.
1517
"""
1618

1719
import asyncio
1820
import inspect
1921
import threading
2022
import time
21-
from unittest.mock import Mock
23+
from unittest.mock import Mock, patch
2224

23-
import httpx
2425
import pytest
25-
import respx
2626

2727
from oilpriceapi import OilPriceAPI
2828
from oilpriceapi.async_client import AsyncOilPriceAPI
@@ -59,6 +59,11 @@ def _post(url, **kwargs):
5959
return _post
6060

6161

62+
def _ok_response(payload=None):
63+
"""A minimal stand-in for a 200 httpx.Response."""
64+
return Mock(status_code=200, json=Mock(return_value=payload or {"status": "success", "data": {}}))
65+
66+
6267
def _track_n(telemetry, n):
6368
for i in range(n):
6469
telemetry.track_request(operation=f"GET /v1/op{i}", duration=0.01, success=True)
@@ -110,12 +115,10 @@ def test_ten_tracked_events_do_not_block_the_calling_thread(sink):
110115
telemetry.close()
111116

112117

113-
@respx.mock
114-
def test_sync_client_requests_are_not_blocked_by_telemetry_delivery(sink):
118+
@patch("httpx.Client.request")
119+
def test_sync_client_requests_are_not_blocked_by_telemetry_delivery(mock_request, sink):
115120
sink.delay = 3.0
116-
respx.get("https://api.oilpriceapi.com/v1/prices/latest").mock(
117-
return_value=httpx.Response(200, json={"status": "success", "data": {}})
118-
)
121+
mock_request.return_value = _ok_response()
119122
client = OilPriceAPI(api_key=API_KEY, enable_telemetry=True)
120123
try:
121124
start = time.monotonic()
@@ -129,12 +132,10 @@ def test_sync_client_requests_are_not_blocked_by_telemetry_delivery(sink):
129132

130133

131134
@pytest.mark.asyncio
132-
@respx.mock
133-
async def test_async_client_event_loop_is_not_blocked_by_telemetry(sink):
135+
@patch("httpx.AsyncClient.request")
136+
async def test_async_client_event_loop_is_not_blocked_by_telemetry(mock_request, sink):
134137
sink.delay = 3.0
135-
respx.get("https://api.oilpriceapi.com/v1/prices/latest").mock(
136-
return_value=httpx.Response(200, json={"status": "success", "data": {}})
137-
)
138+
mock_request.return_value = _ok_response()
138139
client = AsyncOilPriceAPI(api_key=API_KEY, enable_telemetry=True)
139140

140141
ticks = 0
@@ -259,25 +260,25 @@ def close(self):
259260
raise RuntimeError("telemetry close exploded")
260261

261262

262-
@respx.mock
263-
def test_sync_request_result_survives_a_telemetry_failure(sink):
263+
@patch("httpx.Client.request")
264+
def test_sync_request_result_survives_a_telemetry_failure(mock_request, sink):
264265
payload = {"status": "success", "data": {"code": "BRENT_CRUDE_USD", "price": 75.5}}
265-
respx.get("https://api.oilpriceapi.com/v1/prices/latest").mock(
266-
return_value=httpx.Response(200, json=payload)
267-
)
266+
mock_request.return_value = _ok_response(payload)
268267
client = OilPriceAPI(api_key=API_KEY)
269268
client._telemetry = _ExplodingTelemetry()
270-
result = client.request("GET", "/v1/prices/latest")
271-
assert result == payload
269+
try:
270+
result = client.request("GET", "/v1/prices/latest")
271+
assert result == payload
272+
finally:
273+
client._telemetry = Telemetry(enabled=False)
274+
client.close()
272275

273276

274277
@pytest.mark.asyncio
275-
@respx.mock
276-
async def test_async_request_result_survives_a_telemetry_failure(sink):
278+
@patch("httpx.AsyncClient.request")
279+
async def test_async_request_result_survives_a_telemetry_failure(mock_request, sink):
277280
payload = {"status": "success", "data": {"code": "BRENT_CRUDE_USD", "price": 75.5}}
278-
respx.get("https://api.oilpriceapi.com/v1/prices/latest").mock(
279-
return_value=httpx.Response(200, json=payload)
280-
)
281+
mock_request.return_value = _ok_response(payload)
281282
client = AsyncOilPriceAPI(api_key=API_KEY)
282283
client._telemetry = _ExplodingTelemetry()
283284
try:

0 commit comments

Comments
 (0)