Poick

This is a cached version of https://tomwojcik.com/posts/2021-08-18/globally-block-internet-connection-in-django from 2/28/2026, 3:13:56 PM.

Two ways to block internet connection in Python tests | Tom Wojcik

Comparing httpretty and responses.

Two ways to block internet connection in Python tests August 18, 2021 pythontesting I want my tests to never contact any external API. If a test tries to make a real HTTP call, I want it to fail loudly so I know I forgot to add a mock. There are at least two ways to achieve this. 1. httpretty httpretty works by monkey-patching Python’s socket module. When allow_net_connect is set to False, any unmocked request raises httpretty.errors.UnmockedError. You can block network globally with an autouse fixture in conftest.py: import httpretty @pytest.fixture(autouse=True) def mock_responses(): httpretty.enable(allow_net_connect=False) yield httpretty.disable() httpretty.reset() Or use the @httpretty.activate decorator on individual tests: @httpretty.activate(allow_net_connect=False) def test_something(): ... If a test forgets to mock: def test_third_party_api(): requests.get("https://api.example.com/data") httpretty.errors.UnmockedError: Failed to handle network request. Intercepted unknown GET request https://api.example.com/data httpretty also acts as a mocking library. You can register responses, return dynamic bodies via callbacks, and rotate through multiple responses for the same URL: @httpretty.activate(allow_net_connect=False) def test_with_mock(): httpretty.register_uri( httpretty.GET, "https://api.example.com/data", body='{"result": [1, 2, 3]}', content_type="application/json", ) response = requests.get("https://api.example.com/data") assert response.json() == {"result": [1, 2, 3]} # you can also inspect what was sent assert httpretty.last_request().path == "/data" It intercepts all HTTP libraries (requests, urllib, http.client) since it operates at the socket level, which is both a strength and a weakness. httpretty’s maintenance has been inconsistent over the years, and because it replaces the socket at a low level, it can conflict with libraries that also manipulate sockets (like gevent or pytest-asyncio). 2. responses / respx responses is a mocking library for requests, and respx is the equivalent for httpx. Both block unmocked calls by default. When active, any call that doesn’t match a registered mock raises an error immediately. You can block network globally with an autouse fixture in conftest.py, just like with httpretty. The fixture yields the mock object, which tests then use to register mocked responses. With responses (for requests): # conftest.py import responses @pytest.fixture(autouse=True) def mock_responses(): with responses.RequestsMock() as rsps: yield rsps def test_third_party_api(mock_responses): mock_responses.get( "https://api.example.com/data", json={"result": [1, 2, 3]}, ) response = requests.get("https://api.example.com/data") assert response.json() == {"result": [1, 2, 3]} With respx (for httpx): # conftest.py import respx @pytest.fixture(autouse=True) def mock_responses(): with respx.MockRouter() as router: yield router import httpx def test_third_party_api(mock_responses): mock_responses.get("https://api.example.com/data").mock( return_value=httpx.Response(200, json={"result": [1, 2, 3]}) ) response = httpx.get("https://api.example.com/data") assert response.json() == {"result": [1, 2, 3]} An unmocked call fails immediately in both cases: def test_forgot_to_mock(): requests.get("https://api.example.com/other") # ConnectionError: Connection refused by Responses... These libraries only intercept calls made through their respective HTTP client. If something in your codebase uses urllib or http.client directly, they won’t catch it. In practice, if you’ve standardized on requests or httpx, this is not a problem. Which one to pick? httprettyresponses / respxBlocks networkYes (socket-level)Only their respective HTTP clientBuilt-in mockingYesYesSetup effortFixture or context managerFixture or decoratorCatches non-HTTPYesNoActive maintenanceInconsistentYes (Sentry / lundberg)Async supportLimitedrespx natively, aioresponses for aiohttp I’d go with responses or respx depending on which HTTP client you use. They are actively maintained, have clean APIs, and block unmocked calls by default. With an autouse fixture in conftest.py you get a global safety net with minimal setup. httpretty still works and catches more (any socket-level traffic), but given the maintenance track record and the compatibility issues, I’d consider it a legacy choice at this point.