Skip to content

Testing SMS

TestSmsService is a built-in test double for ISmsService with call recording, configurable responses, and exception injection.

Setup

var smsService = new TestSmsService();
var runtime = TestAppRuntime.Create()
    .WithSmsService(smsService);

Call Recording

await program.RunAsync(runtime);

// Assert sends
await Assert.That(smsService.SendCalls).HasCount().EqualTo(1);
await Assert.That(smsService.SendCalls[0].Body).Contains("verification code");
await Assert.That(smsService.SendCalls[0].To).IsEqualTo(new PhoneNumber("+15559876543"));
await Assert.That(smsService.SendCallCount).IsEqualTo(1);

// Assert status checks
await Assert.That(smsService.StatusCalls).HasCount().EqualTo(1);

Recording Properties

Property Type Description
SendCalls IReadOnlyList<SmsMessage> All SendAsync calls
StatusCalls IReadOnlyList<SmsMessageId> All GetStatusAsync calls
SendCallCount int Number of SendAsync calls

Custom Responses

smsService.OnSend = msg => new SmsResult
{
    Id = SmsMessageId.New(),
    ProviderMessageId = "twilio-sid-123",
    Status = SmsStatus.Sent,
    SegmentCount = 2
};

smsService.OnGetStatus = id => new SmsResult
{
    Id = id,
    ProviderMessageId = "twilio-sid-123",
    Status = SmsStatus.Delivered
};

Exception Injection

smsService.SendException = new HttpRequestException("Twilio unavailable");

var result = await program.RunAsync(runtime);
await Assert.That(result).IsFail();

Reset

smsService.Reset();
// All calls cleared, OnSend/OnGetStatus/SendException reset to null

Full Example

[Test]
public async Task AppointmentReminder_SendsSms()
{
    var smsService = new TestSmsService();
    var runtime = TestAppRuntime.Create()
        .WithSmsService(smsService)
        .WithStubAppointmentStore(stub => stub
            .OnGetById(_ => Task.FromResult<Appointment?>(TestData.SampleAppointment)));

    await ReminderWorkflows.SendReminder(TestData.AppointmentId).RunAsync(runtime);

    await Assert.That(smsService.SendCalls).HasCount().EqualTo(1);
    await Assert.That(smsService.SendCalls[0].Body).Contains("Reminder");
}