web-development

Your mocked webhooks are lying to you

gokul
August 13, 2026
2 min read

Every integration test suite has them: hand-written webhook payloads, crafted from the provider's docs, passing green in CI. Then the integration ships, a real event arrives, and something breaks that the mocks never caught.

The gap is structural. A mock is your understanding of the payload, not the payload. The docs show you the fields that exist today, in the examples they chose, with the formatting they remembered to document.

Real events carry the rest: the optional field that's suddenly null, the amount that's a string in one event type and an integer in another, the timestamp format that differs between test mode and live mode, the legacy field that still fires for accounts created before 2023.

None of this is the provider being sloppy — it's the normal drift between documentation and production systems. But your mock freezes your first reading of the docs in amber, and every test that passes against it confirms a version of reality that may no longer exist.

The fix isn't abandoning mocks — they're fine for logic tests. It's adding one habit: capture real payloads and test against those. When you first build the integration, record what the provider actually sends — every tunnel with a request inspector does this (we build 21tunnel for it: https://21tunnel.com, ngrok's inspector works too). Save those real deliveries as fixtures. Now your tests run against what the internet actually sends you, and when the provider's payload drifts, your nex captured fixture catches it.

A mock tells you your code handles the webhook you imagined. A captured payload tells you it handles the one you actually get. Only one of those is true.

Join the Conversation

Share Your Thoughts

Minimum 10 characters0 / 2000