Skip to content

Testing Notifications

Deepstaging provides TestNotificationChannel and TestNotificationStore — test doubles with call recording and typed query APIs. No mocking libraries needed.

TestNotificationChannel

Records every SendAsync and SendManyAsync call. Query sent notifications by type or recipient.

var channel = new TestNotificationChannel();

// ... run your handler that sends notifications ...

// Assert a notification was sent to a specific recipient
var sent = channel.SentTo("user-42");
await Assert.That(sent).Count().IsEqualTo(1);
await Assert.That(sent[0].Type).IsEqualTo("order.confirmed");

Call Recording

Property Type Description
Sent IReadOnlyList<Notification> All notifications sent through this channel
SendCallCount int Number of SendAsync calls
SendManyCallCount int Number of SendManyAsync calls

Typed Queries

Method Returns Description
SentByType(string type) IReadOnlyList<Notification> Notifications matching a type (e.g., "order.confirmed")
SentTo(string recipientId) IReadOnlyList<Notification> Notifications for a specific recipient

TestNotificationStore

Records SaveAsync, MarkReadAsync, and MarkAllReadAsync calls. Seed stored notifications for retrieval queries.

var store = new TestNotificationStore();

// Seed a notification for the read-status flow
store.Seed(new StoredNotification(
    "notif-1", "order.confirmed", "user-42",
    "Your order shipped", null, false, DateTimeOffset.UtcNow));

// ... run your handler ...

// Assert notifications were marked read
await Assert.That(store.MarkedReadIds).Contains("notif-1");

Call Recording

Property Type Description
SavedNotifications IReadOnlyList<Notification> All notifications passed to SaveAsync
MarkedReadIds IReadOnlyList<string> All IDs passed to MarkReadAsync
MarkedAllReadRecipients IReadOnlyList<string> All recipient IDs passed to MarkAllReadAsync

Typed Queries

Method Returns Description
SavedByType(string type) IReadOnlyList<Notification> Saved notifications matching a type
SavedTo(string recipientId) IReadOnlyList<Notification> Saved notifications for a specific recipient

Seeding

store.Seed(new StoredNotification(
    Id: "n-1",
    Type: "order.shipped",
    RecipientId: "user-42",
    Message: "Your order is on its way",
    Payload: null,
    IsRead: false,
    CreatedAt: DateTimeOffset.UtcNow));

Seeded notifications are returned by GetAsync and GetUnreadCountAsync.

Reset Between Tests

Both test doubles support Reset() to clear recorded calls and seeded state:

channel.Reset();
store.Reset();