Skip to main content

Guide

How to Mock the Resend API in Tests

Stop sending real emails from your test suite. Here is a stateful Resend mock you can point your client at.

Apr 10, 2026FetchSandbox Engineering

Mocking the Resend API in tests is one of those small problems that turn into a paper cut every week. You write a quick handler stub, it works, then you forget you have it, then someone runs the test suite without the stub configured, and now your CEO gets a “welcome to the platform” email at 2am because someone's integration test ran against production.

There are three real ways to mock Resend, and they have different tradeoffs.

Option 1: Hand-rolled fetch mock

Easiest to start. Stub fetch in your test, return a fake email response, move on. This works for a single isolated test where you only care that the handler called Resend with the right payload.

It stops being enough the moment you need to test what happens after the email is sent — the email.delivered webhook, the bounce, the open, the click. None of those events fire from a fetch stub. You can hand-write events too, but now you are maintaining a fake.

Option 2: Resend test mode

Resend has a test mode where emails are not actually delivered. Useful for end-to-end tests against the real API surface. The downsides: you still need a Resend API key in CI, your test mode emails count toward dashboard usage, and you cannot fire specific events (bounce, complaint) on demand.

Option 3: A stateful Resend sandbox

FetchSandbox runs a stateful mock of the entire Resend API — all 83 endpoints, full email lifecycle, audiences, contacts, broadcasts, domains, and webhook events. Spin one up in 2 seconds, point your Resend client at the sandbox URL, and run your tests.

# 1. Spin up a Resend sandbox
curl -X POST https://fetchsandbox.com/api/sandboxes \
  -H "Content-Type: application/json" \
  -d '{"spec_id":"resend"}'

# Returns: { id, base_url, credentials: [{ api_key }] }

# 2. In your test, set the Resend base URL
process.env.RESEND_BASE_URL = sandbox.base_url
process.env.RESEND_API_KEY = sandbox.credentials[0].api_key

# 3. Run your tests — emails get "sent" to the sandbox, never delivered

The hard part nobody talks about

Most Resend integration bugs are not in the send call. They are in the bounce handler. Bounces are rare in normal traffic, hard to fire on demand against the real API, and easy to miss in tests. Your handler should:

  • Distinguish hard bounces from soft bounces
  • Decrement a delivery score for repeated soft bounces from the same address
  • Suppress sends to addresses that hit the hard-bounce threshold
  • Survive a bounce event being delivered twice

With FetchSandbox you can fire email.bounced on demand, replay it, and watch your handler do the right thing every time.

Where to go from here