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¶
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");
}