DEV Community

Receive SMS
Receive SMS

Posted on

Mock or real SMS in your tests? A practical split

Every app with phone verification faces the same question in its test suite: do we mock the SMS provider or send real messages? The answer is "both, in different places". Here's the split that has worked for us.

Mock in unit and integration tests

Most tests don't care whether an SMS really left the building. They care that your code:

  • generates a code with the right length and expiry,
  • stores it hashed, not in plain text,
  • rate-limits requests per number and per IP,
  • invalidates old codes correctly,
  • calls the provider with the right parameters.

For all of that, inject a fake SMS client that records what it was asked to send. It's fast, free and deterministic. Run it on every commit.

class FakeSms:
    def __init__(self):
        self.sent = []
    def send(self, to, text):
        self.sent.append((to, text))

def test_code_is_sent(app):
    sms = FakeSms()
    app.sms = sms
    app.request_code("+447700900123")
    assert sms.sent[0][0] == "+447700900123"
Enter fullscreen mode Exit fullscreen mode

Use real SMS for delivery checks

Mocks can't tell you that:

  • a country started rejecting your sender ID,
  • your provider's route to one carrier degraded,
  • a template change pushed the message into UCS-2 and two parts,
  • codes take 90 seconds to arrive in one region.

Those only show up with real messages to real numbers. Run a small set of end-to-end checks on a schedule (nightly, or hourly for critical markets) against staging, using online numbers in the countries you care about. Log delivery time and the sender ID you received, and alert when they change.

I run Receive SMS, which has an API for this: buy a number for a country, trigger your sign-up, poll for the SMS, and you're only charged if it arrives. Any provider with a similar API works the same way.

The split in one table

Test type SMS Runs Checks
Unit / integration Fake client Every commit Logic, limits, storage
E2E delivery Real numbers Nightly / hourly Delivery, speed, sender ID, text

Keep the real-SMS suite small. A handful of countries and one happy path each is usually enough to catch the problems mocks can't see.

Top comments (0)