Mocking an external HTTP API (courier, payment gateway) in tests

Backend Live Coding November 13, 2026 python

I mock at the HTTP boundary, not my own function, so parsing, timeouts and retry are tested too.

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# ======================================================================
# Q: How do you mock an external HTTP API (e.g. a courier or payment gateway)?
#
# I mock at the HTTP boundary, not my own function, so parsing, timeouts and
# retry are tested too. I always test the unhappy paths: 5xx, timeout, invalid
# JSON, 429 with Retry-After. Most production bugs in the e-shops came from
# there.
# ======================================================================

# httpx -> respx
import httpx, respx

@respx.mock
def test_courier_label_retry_on_503():
    route = respx.post('https://api.courier.gr/v2/labels').mock(side_effect=[
        httpx.Response(503),
        httpx.Response(201, json={'tracking': 'GR123'}),
    ])
    assert create_label(order_id=5) == 'GR123'
    assert route.call_count == 2

# requests -> responses
import responses

@responses.activate
def test_payment_declined():
    responses.post('https://pay.example.com/charges',
                   json={'status': 'declined', 'code': 'insufficient_funds'}, status=402)
    with pytest.raises(PaymentDeclined):
        charge(order_id=5, amount_cents=1999)