Snapshot testing Verify.MongoDB
Verify
is a snapshot tool created by Simon Cropp. It takes inspiration from ApprovalTests
and makes it easy to assert complex data models and documents (e.g. as part of a unit test).
What I like about this technique is that if the data model or document is different to what the test expects, then not only does the test fail, but for local development, it can automatically launch familiar diff tools. One of my favourites is Beyond Compare, and it makes it very easy to identify what the actual differences are.
In addition to the main Verify library, Simon and others have also created extension packages to provide additional support for more specific cases (like Verify.AspNetCore
, Verify.EntityFramework
, Verify.ImageSharp
, Verify.NServiceBus
and more).
I was doing some work with Azure Cosmos DB using the Mongo API with .NET and thought it would be useful to be able to write some tests to capture what actual queries are being sent over the wire.
I'd recently listened to an episode of The Unhandled Exception podcast where Dan Clarke interviewed Simon on Snapshot Testing. He gave the example of using the Verify.EntityFramework
extension package to write unit tests that would validate the SQL that Entity Framework was generating.
This made me wonder if I could do something similar for MongoDB. After reviewing how the Verify.EntityFramework
extension worked, I took a closer look at the MongoDB .NET Driver library to see what hooks were available. After a bit of trial and error, I figured out how it was possible!
You can write a unit test that includes code like this:
MongoDBRecording.StartRecording();
await collection.FindAsync(Builders<BsonDocument>.Filter.Eq("_id", "blah"),
new FindOptions<BsonDocument, BsonDocument>());
await Verifier.Verify("collection");
The verified file would have the following content:
{
target: collection,
mongo: [
{
Database: VerifyTests,
Document: {
filter: {
_id: blah
},
find: docs
},
Type: Started,
Command: find,
StartTime: DateTimeOffset_1,
OperationId: Id_1,
RequestId: Id_2
},
{
Document: {
cursor: {
firstBatch: [],
id: 0,
ns: VerifyTests.docs
},
ok: 1.0
},
Type: Succeeded,
Command: find,
StartTime: DateTimeOffset_2,
OperationId: Id_1,
RequestId: Id_2
}
]
}
That's a representation of what would be sent over the wire by the query in the test. It's an ideal opportunity to confirm that the query is doing what you intended. For pay-per-use services like Cosmos DB, it's critical that your queries are as efficient as possible. Otherwise, it might cost you too much, and your queries might end up rate-limited.
After confirming it worked as I'd hoped, I figured it could be something that others might find useful, so I created a NuGet package. I got in touch with Simon to find out how best to get it published on nuget.org. He was most helpful, and I'm pleased to report that the package is now available at https://www.nuget.org/packages/Verify.MongoDB/, and the source repository is at https://github.com/flcdrg/Verify.MongoDB.
If you're building an application that's using the MongoDB .NET Driver then this package will help you create some useful snapshot tests.
Check it out!
Categories: .NET, Unit Testing