Every mock SMTP library tells you one thing: “the send function was called.” That’s useful for unit tests. For end-to-end validation of email flows — password resets, OTP codes, magic links, multi-step approval workflows — it falls short.
Real emails fail silently in ways mocks never do: broken MIME structure, mangled attachment encoding, malformed HTML that renders fine in your browser but blank in Outlook, one-time tokens that don’t work because the URL was truncated, invite links that redirect wrong because the token expired three seconds early.
Here are six real workflows where teams swapped mocks for actual SMTP infrastructure and caught bugs their tests never caught before.
1. OTP / 2FA Verification Flows
The Problem: Login tests with OTP either mock the delivery (zero real coverage) or share a real inbox across parallel tests (flaky, order-dependent, CI-unsafe).
The MailFork Approach:
- Create one team inbox:
[email protected] - Each test creates a 1-hour ephemeral alias with a unique tag
- App sends OTP to the alias
extractOtp()polls and returns the code in < 1s
The Result: Real SMTP delivery, real OTP parsing, zero flakiness. Your entire login flow — email send to extraction — exercises the same code path your users hit. If the MIME structure is wrong or the OTP format doesn’t match your parser, the test fails.
2. Magic Link / Passwordless Auth
The Problem: Magic link tests need to capture the token from a real email, not hardcode it. Mocking the email service means you’re not testing template rendering, URL embedding, or link extraction.
The MailFork Approach:
- Trigger password reset in your app
extractUrl()scans the email HTML for the link matchingbuttonText: 'Sign in'- Returns the full URL with the one-time token
- Playwright test follows it directly
The Result: The test exercises the same code path your users hit. If the email template breaks, the test fails. If the token isn’t correctly embedded, you catch it immediately.
3. Approval Workflow Emails
The Problem: Multi-step approvals send several emails (request submitted, approval required, confirmation). Hard to test end-to-end without a real inbox. Mocks can’t validate email sequences or link extraction from multiple emails.
The MailFork Approach:
- Scope each extraction to
subjectorbuttonText - Use
Promise.allto extract Approve and Reject URLs from the same email simultaneously - Follow both links to validate the outcome
The Result: Full workflow coverage from submission to outcome. Validate email ordering, confirm both approval and rejection paths work, and test the business logic end-to-end.
4. CI/CD Pipelines — Parallel Test Runs
The Problem: Parallel CI workers share an inbox. Emails from one worker contaminate another. Building per-worker isolation adds overhead and error-prone cleanup logic.
The MailFork Approach:
- Each CI worker creates its own ephemeral alias:
ci+run-{Date.now()}-{Math.random()} - All SDK calls pass the
aliasTag— completely isolated - Aliases auto-expire after 1 hour; no cleanup code needed
The Result: 4 workers, 4 aliases, zero cross-contamination. Works out of the box with GitHub Actions, GitLab CI, CircleCI, and any platform. No custom setup, no per-worker databases, no manual teardown.
5. Email Content Regression Testing
The Problem: A template change silently breaks the plain-text version. HTML looks fine but Outlook users get blank emails. Mocks validate that a template was rendered; they can’t validate that the output is readable.
The MailFork Approach:
- MailFork stores both HTML and plain-text parts from the real MIME
- Assert on both:
email.body.textandemail.body.html - Check attachment encoding:
email.attachments[0].filename
The Result: A one-line template typo fails the test before production. Your tests validate the actual email content users receive, not just that the send function was called.
6. Invite Acceptance Flows
The Problem: User invites send links with short-lived tokens. Hard to test without capturing the real email. One-time-use enforcement, expiry windows, and redirect behavior are easy to break and hard to mock correctly.
The MailFork Approach:
- Trigger the invite flow
extractUrl()withbuttonText: 'Accept Invite'grabs the token-bearing URL- Test follows it to complete the flow
- (Optional) Use an ephemeral alias to isolate the test
The Result: Invite token expiry, one-time-use enforcement, and redirect behavior — all covered. You validate that the real token in the real email works correctly.
What’s the pattern?
Real email infrastructure isn’t just more thorough — it’s simpler to work with. You don’t need complex fixtures, shared state management, or custom isolation logic. Aliases are ephemeral by default. Extraction is polling-based, so async operations work naturally. And because you’re using actual SMTP, your tests validate the full delivery path, not a simulation of it.
Start with your most critical email flow: password resets, login OTP, or account creation. Spend 10 minutes setting up a MailFork team inbox and an API key. Then write one test. You’ll immediately see things mocks never caught.
Want to try it? Get started in 10 minutes →