-
Notifications
You must be signed in to change notification settings - Fork 1
Integration MongoDB Extension
The Kronikol.Extensions.MongoDB package adds MongoDB operation tracking to your test diagrams using the driver's built-in command monitoring events. Instead of opaque internal database calls, your sequence diagrams show classified operations like Find → users with a clean mongodb:///mydb/users URI.
Using a shared library or abstraction layer? If your code doesn't use the MongoDB driver directly — e.g. it goes through a shared repository library, wrapper, or custom abstraction — this extension won't be able to hook into the driver's command monitoring. See Tracking Custom Dependencies for alternative approaches including
RequestResponseLogger.LogPair(),TrackingProxy<T>, andMessageTracker.
The MongoDB .NET driver provides a first-class event subscription API via MongoClientSettings.ClusterConfigurator. MongoDbTrackingSubscriber subscribes to three events:
-
CommandStartedEvent— captures the command name, BsonDocument, and database namespace -
CommandSucceededEvent— captures the reply and duration -
CommandFailedEvent— captures the exception
The subscriber correlates start→success/failure pairs using RequestId via a ConcurrentDictionary, then logs both a request and response entry to RequestResponseLogger. Because it logs to the same logger as the standard TestTrackingMessageHandler, MongoDB operations appear alongside your HTTP API calls in the same sequence diagram.
dotnet add package Kronikol.Extensions.MongoDB| Level | Label shown | URI shown | Request content | Response content |
|---|---|---|---|---|
| Raw | Find mydb.users filter={...} |
mongodb:///mydb/users |
Full BSON command | Full BSON reply |
| Detailed | Find → users |
mongodb:///mydb/users |
Filter text only | Metadata + document preview |
| Summarised | Find |
mongodb:///mydb |
None | Metadata + document preview |
The default is Detailed.
| Category | Operations |
|---|---|
| CRUD |
Find, Insert, Update, Delete
|
| Aggregation |
Aggregate, Count, Distinct
|
| Atomic | FindAndModify |
| Batch | BulkWrite |
| DDL |
CreateIndex, DropIndex, CreateCollection, DropCollection, RenameCollection
|
| Metadata |
ListCollections, ListDatabases, ListIndexes
|
| Change Streams |
Watch (detected via $changeStream in aggregate pipeline) |
| Transactions |
CommitTransaction, AbortTransaction
|
| Admin |
DropDatabase, ServerStatus, DbStats, CollStats
|
| Legacy | MapReduce |
| Cursor |
GetMore (disabled by default) |
| Fallback |
Other (unrecognised commands) |
In Detailed verbosity, labels include directional arrows indicating the data flow:
| Direction | Arrow | Examples |
|---|---|---|
| Read | ← |
Find ← users, Aggregate ← orders, Count ← items, Distinct ← items, Watch ← orders, GetMore ← users, ListIndexes ← users
|
| Write | → |
Insert (×5) → users, Update → orders, Delete → orders, BulkWrite → users, DropCollection → temp
|
| Read-modify-write | ↔ |
FindAndModify ↔ users |
| Schema / Admin | (none) |
CreateIndex, ServerStatus, CommitTransaction
|
For Aggregate and Watch operations, the label includes the pipeline stage names when available. For example:
Aggregate ($match, $group, $sort) ← ordersWatch ($changeStream) ← orders
Collections ending in .files or .chunks are automatically annotated with (GridFS):
Find (GridFS) ← uploads.files
Insert operations with multiple documents include a count:
Insert (×5) → users
The collection name is extracted from the first element of the BsonDocument command. For example:
-
{ "find": "users", "filter": {...} }→ collection =users -
{ "insert": "orders", "documents": [...] }→ collection =orders -
{ "aggregate": 1, "pipeline": [...] }→ database-level aggregate, collection = null
var trackingOptions = new MongoDbTrackingOptions
{
ServiceName = "MongoDB",
CallerName = "My API",
Verbosity = MongoDbTrackingVerbosity.Detailed,
CurrentTestInfoFetcher = CurrentTestInfo.Fetcher
};
var settings = MongoClientSettings.FromConnectionString("mongodb://localhost:27017");
settings.WithTestTracking(trackingOptions);
var client = new MongoClient(settings);WithTestTracking chains a tracking subscriber into ClusterConfigurator without replacing any existing configurator. This requires no production code changes.
If you need more control:
var trackingOptions = new MongoDbTrackingOptions
{
ServiceName = "MongoDB",
CallerName = "My API",
Verbosity = MongoDbTrackingVerbosity.Detailed,
CurrentTestInfoFetcher = CurrentTestInfo.Fetcher
};
var subscriber = new MongoDbTrackingSubscriber(trackingOptions);
var settings = MongoClientSettings.FromConnectionString("mongodb://localhost:27017");
settings.ClusterConfigurator = builder => subscriber.Subscribe(builder);
var client = new MongoClient(settings);builder.ConfigureTestServices(services =>
{
services.AddSingleton<IMongoClient>(sp =>
{
var trackingOptions = new MongoDbTrackingOptions
{
ServiceName = "MongoDB",
CallerName = "My API",
Verbosity = MongoDbTrackingVerbosity.Detailed,
CurrentTestInfoFetcher = CurrentTestInfo.Fetcher
};
var settings = MongoClientSettings.FromConnectionString("mongodb://localhost:27017");
settings.WithTestTracking(trackingOptions);
return new MongoClient(settings);
});
});The simplest approach — registers a MongoDbTrackingSubscriber singleton with IHttpContextAccessor auto-resolved from DI:
builder.ConfigureTestServices(services =>
{
services.AddMongoDbTestTracking(options =>
{
options.ServiceName = "MongoDB";
options.Verbosity = MongoDbTrackingVerbosity.Detailed;
});
});| Property | Type | Default | Description |
|---|---|---|---|
ServiceName |
string |
"MongoDB" |
The participant name shown in the diagram for the MongoDB service |
CallerName |
string |
"Caller" |
The participant name shown for the service making MongoDB calls |
Verbosity |
MongoDbTrackingVerbosity |
Detailed |
Controls how much detail appears in the diagram (Raw, Detailed, Summarised) |
CurrentTestInfoFetcher |
Func<(string Name, string Id)>? |
null |
Returns the current test's name and ID. Required — if null, commands are monitored but not logged |
CurrentStepTypeFetcher |
Func<string?>? |
null |
Optional — returns the current BDD step type (Given/When/Then) |
ExcludedOperations |
HashSet<MongoDbOperation> |
[] |
Operations to suppress from tracking entirely (e.g. suppress ListDatabases or ServerStatus noise) |
LogFilterText |
bool |
true |
When true, includes the filter document text in Detailed mode request content |
AutoCorrelateWrites |
bool |
true |
When true, tracked write operations (Insert, Update, FindAndModify) auto-populate TestCorrelationStore for parallel-safe background thread correlation (e.g. Change Stream attribution). See Change Stream Correlation
|
LogResponseContent |
bool |
true |
Include response content (documents from cursor.firstBatch) in diagram response arrows at all verbosity levels (v2.37.3+). At Raw, the full reply is always shown regardless. Set to false to restore previous empty-arrow behaviour |
MaxResponseDocuments |
int |
10 |
Maximum number of documents to include from cursor.firstBatch in response content (v2.37.0+) |
v2.23.0+ Dual-Resolution:
MongoDbTrackingSubscriberaccepts an optionalIHttpContextAccessor? httpContextAccessorconstructor parameter for resolving test identity from HTTP request headers when running inside the SUT's request pipeline. See HTTP Tracking Setup#Dual-Resolution Test Identity (v2.23.0+) for details.
| IgnoredCommands | HashSet<string> | See below | Commands to ignore entirely (not logged even when test info is available) |
| TrackGetMore | bool | false | Whether to track getMore cursor continuation commands |
| SetupVerbosity | MongoDbTrackingVerbosity? | null | Verbosity override for the Setup phase. See Phase-Aware Tracking |
| ActionVerbosity | MongoDbTrackingVerbosity? | null | Verbosity override for the Action phase. See Phase-Aware Tracking |
| TrackDuringSetup | bool | true | When false, tracking is suppressed during Setup. See Phase-Aware Tracking |
| TrackDuringAction | bool | true | When false, tracking is suppressed during Action. See Phase-Aware Tracking |
These MongoDB internal/handshake commands are ignored by default:
-
isMaster,hello— server handshake -
saslStart,saslContinue— authentication -
ping— health check -
buildInfo— server metadata -
getLastError— legacy error check -
killCursors— cursor cleanup -
endSessions— session cleanup
Override IgnoredCommands to customise:
new MongoDbTrackingOptions
{
IgnoredCommands = ["isMaster", "hello"] // Only ignore these two
}MongoDbTrackingSubscriber implements ITrackingComponent and auto-registers with TrackingComponentRegistry. The invocation count increments for every command (including ignored ones), so you can verify MongoDB was actually contacted:
var subscriber = new MongoDbTrackingSubscriber(options);
// ... run test ...
Assert.True(subscriber.WasInvoked);
Assert.Equal(3, subscriber.InvocationCount);Or use TrackingComponentRegistry.GetUnusedComponents() to find services that were wired up but never called.
Response arrows in diagrams show document data from cursor.firstBatch instead of being empty. At Detailed and Summarised verbosity, response content includes metadata and document previews. At Raw, the full BSON reply is always shown.
Response content is shown at all verbosity levels when LogResponseContent = true (the default). Set LogResponseContent = false to restore previous empty-arrow behaviour.
new MongoDbTrackingOptions
{
Verbosity = MongoDbTrackingVerbosity.Summarised,
LogResponseContent = true, // default — show response data
MaxResponseDocuments = 10 // capture up to 10 documents (default: 10)
}Note: MongoDB uses
MaxResponseDocumentsinstead ofMaxResponseRowssince responses contain BSON documents rather than tabular rows.
If your application uses MongoDB Change Streams, background processing generates tracking entries on threads where test context is unavailable. ChangeStreamCorrelation attributes change items back to the originating test using TestCorrelationStore.
When AutoCorrelateWrites is true (the default), every tracked write (Insert, Update, FindAndModify) populates TestCorrelationStore with the document ID. When the Change Stream processes that document, ChangeStreamCorrelation looks up the test identity from the store.
Wraps a single-item Change Stream handler:
ChangeStreamCorrelation.Wrap<MyDocument>(
async (item, ct) =>
{
await ProcessChange(item);
},
serviceName: "MongoDB",
idSelector: doc => doc.Id)Wraps a batch handler:
ChangeStreamCorrelation.WrapBatch<MyDocument>(
async (items, ct) =>
{
foreach (var item in items)
await ProcessChange(item);
},
serviceName: "MongoDB",
idSelector: doc => doc.Id)See Background Thread Correlation and Parallel-Safe Background Correlation for more details on the correlation system.
The subscriber uses ConcurrentDictionary<int, PendingOperation> keyed by RequestId to correlate CommandStartedEvent → CommandSucceededEvent/CommandFailedEvent. This handles concurrent operations correctly — multiple in-flight commands on different connections don't interfere with each other.
If a CommandSucceededEvent or CommandFailedEvent arrives without a matching CommandStartedEvent (e.g., due to race conditions or late subscription), it is silently ignored.
Getting Started
Common Tasks
Integration Guides
- Integration xUnit3
- Integration xUnit2
- Integration NUnit
- Integration MSTest
- Integration TUnit
- Integration BDDfy xUnit3
- Integration LightBDD xUnit2
- Integration LightBDD xUnit3
- Integration LightBDD TUnit
- Integration ReqNRoll xUnit2
- Integration ReqNRoll xUnit3
- Integration ReqNRoll TUnit
Extensions
- Integration AtlasDataApi Extension
- Integration BigQuery Extension
- Integration Bigtable Extension
- Integration BlobStorage Extension
- Integration ClickHouse Extension
- Integration CloudStorage Extension
- Integration CosmosDB Extension
- Integration Dapper Extension
- Integration DynamoDB Extension
- Integration EF Core Relational Extension
- Integration Elasticsearch Extension
- Integration EventBridge Extension
- Integration EventHubs Extension
- Integration Grpc Extension
- Integration Kafka Extension
- Integration MassTransit Extension
- Integration MongoDB Extension
- Integration MySqlConnector Extension
- Integration Npgsql Extension
- Integration Oracle Extension
- Integration PubSub Extension
- Integration Redis Extension
- Integration S3 Extension
- Integration ServiceBus Extension
- Integration SNS Extension
- Integration Spanner Extension
- Integration SqlClient Extension
- Integration Sqlite Extension
- Integration SQS Extension
- Integration StorageQueues Extension
- Integration OpenTelemetry Extension
- Integration DispatchProxy Extension
- Integration MediatR Extension
- Integration PlantUML IKVM
Configuration
- Tracking Dependencies
- Tracking Custom Dependencies
- HTTP Tracking Setup
- Report Configuration
- Diagram Customisation
- Phase-Aware Tracking
- Content Formatting
- PlantUML Server Configuration
Features
- Generated Reports
- Search Syntax
- Component Diagrams
- PlantUML Browser Rendering
- Inline SVG Rendering
- Internal Flow Tracking
- Tags and Attributes
- Excluding Requests
- Excluded Headers
- Multi-Host Test Architectures
- Event-Driven Architecture Testing
- Service Bus Tracking Patterns
- Background Thread Correlation
- Parallel-Safe Background Correlation
- Event & Message Tracking
- Assertion Tracking
- Step Tracking
- Tabular Attributes
- Large Response and Diagram Handling
- Diagnostics and Debugging
- CI Summary Integration
- CI Artifact Upload
- Merging Parallel Reports
Reference