Two ways to block internet connection in Python tests

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 / respx
Blocks networkYes (socket-level)Only their respective HTTP client
Built-in mockingYesYes
Setup effortFixture or context managerFixture or decorator
Catches non-HTTPYesNo
Active 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.