C# Testcontainers For MongoDB: How To Easily Run Local Databases

Dev LeaderDev Leader
8 min read

In this article, I’ll guide you through C# Testcontainers for MongoDB! I love using Testcontainers for local database work when I don’t want to think about managing the overhead of spinning up and tearing down a database, or managing something in the cloud. MongoDB is no exception here are the C# Testcontainers NuGet package that we have for MongoDB is a dream to work with.

In this article, I’ll introduce you to the basics of Testcontainers. From there, I’ll demonstrate how simple it is to interact with your newly created database via the C# MongoDB.Driver NuGet package — almost like you wouldn’t even know there was a container spun up! Let’s dive into it.


Overview of C# Testcontainers

Testcontainers is an awesome NuGet package that can greatly enhance your testing and local development workflow when building .NET applications. It provides a simple and effective way to manage Docker containers, allowing you to spin up lightweight and isolated instances and have them tear down like nothing ever happened!

That means with Testcontainers, you no longer have to worry about setting up and tearing down test databases or dealing with complex configuration files. It handles all the details of container management, making this process feel trivial — I sure wouldn’t want to handle this manually.

Some of the key benefits of Testcontainers include:

  • Its ability to provide a consistent and reproducible test environment. You can define the exact service version and configuration that you require, ensuring that your test results are reliable and consistent across different environments.

  • The speed and flexibility it brings to your testing and development workflow. By using lightweight Docker containers, you can quickly spin up and tear down test environments on demand. No configuring cloud or shared resources ahead of time… Just on-the-fly awesomeness.

  • Seamless integration with existing testing frameworks and tools in the DotNet ecosystem, such as Xunit, NUnit, and BenchmarkDotNet. This allows you to easily incorporate containerized service instances into your existing test suites without any major modifications.

For this article, we’ll be focused on how we can use C# Testcontainers for MongoDB in particular. Much of the advice covered here will be applicable to other services, especially databases, but we’ll keep our sights set on MongoDB.


Setting Up Testcontainers in C#

To get started with Testcontainers in C#, you’ll need to install and configure the necessary dependencies in your project. Follow the steps below to set up Testcontainers for MongoDB in C#.

1. Installing Testcontainers

Generally, the first step would be to install the Testcontainers NuGet package in your C# project. You would open the NuGet Package Manager Console and run the following command:

Install-Package Testcontainers

However, we need the MongoDB flavor of this package (I am using version 3.8.0 at the time of writing) which includes the base Testcontainers package. You can install via the package manager user interface or with this command:

Install-Package Testcontainers.MonogoDB

2. Configuring Testcontainers for MongoDB

Once you have installed Testcontainers, you need to configure it for MongoDB. This involves setting up a MongoDB container with the required settings. Here is an example of how you can configure Testcontainers for MongoDB in C#:

using Testcontainers.MongoDb;

MongoDbContainer container = new MongoDbBuilder()
    .WithImage("mongo:latest")
    .Build();

In the above example, we create a new instance of the MongoDbBuilder and specify the MongoDB image and port binding. The WithImage method sets the image for the MongoDB container, so using “mongo:latest” will always pull the latest image.

Optionally, we could use port binding to configure which ports we want to be using explicitly:

using Testcontainers.MongoDb;

MongoDbContainer container = new MongoDbBuilder()
    .WithImage("mongo:latest")
    .WithPortBinding(1337, 27017)
    .Build();

The code above uses WithPortBinding method binds the container’s port 27017 to the host machine’s port 1337. We’ll see in the upcoming sections that unless you have a specific need to bind ports, you can potentially just leave this be. We can get a dynamic connection string, which is very convenient!

3. Starting and Stopping the MongoDB Container

After configuring Testcontainers for MongoDB, you can start and stop the container as needed. Here are code examples for starting and stopping the container:

To start the MongoDB container:

await container.StartAsync();

To stop the MongoDB container:

await _container.StopAsync();

Remember the MongoDbContainer type can be disposed of, so call DisposeAsync to cleanup when you’re ready.


Using C# Testcontainers for MongoDB in Practice

Now that we’ve seen how to spin up and tear down containers, what are we supposed to do with them? We have plenty of options, and truly, the limit is your own imagination (and time, money, and other resources…)!

Most people leverage C# Testcontainers for writing integration or functional tests. You can match up Testcontainers with xUnit or NUnit, for example, and write tests that interact with a real database.

For me, I needed to go wire C# Testcontainers for MongoDB up to BenchmarkDotNet so I could benchmark inserting records into MongoDB! A similar use case where I needed transient local databases, but not necessarily for a test framework.

Regardless, we need to be able to connect to these MongoDB database containers from C#, and these next subsections will cover that.

Connecting to C# Testcontainers for MongoDB with MongoDB.Driver

Let’s assume you read the earlier sections and you have the correct MongoDB package installed for Testcontainers. If you skimmed ahead to this section, go back, read it, and get the right package. Otherwise, you’ll be scratching your head about why you can’t find the right dependencies!

You’ll also need to get the MongoDB.Driver NuGet package installed. This is what we’re going to be using to establish a connection to the database container that we spun up. I have other articles you can read if you want more explanation on how MongoDB.Driver works in general:

With the right packages ready to go, we can combine the code we saw earlier with some MongoDB driver code to get things glued together:

using MongoDB.Bson;
using MongoDB.Driver;

using Testcontainers.MongoDb;

MongoDbContainer container = new MongoDbBuilder()
    .WithImage("mongo:latest")
    .Build();
await container.StartAsync();
string connectionString = container.GetConnectionString();

MongoClient mongoClient = new MongoClient(connectionString);
IMongoDatabase database = mongoClient.GetDatabase("test");
IMongoCollection<BsonDocument> collection = database.GetCollection<BsonDocument>("test");

In the example above, we can call GetConnectionString() on the newly spun up MongoDB container from Testcontainers. The awesome part about this is that no matter how you configure your Testcontainer for MongoDB using the builder pattern we see in this code and earlier in the article, GetConnectionString() will get you what you need to connect.

Because MongoClient takes in a connection string as a single argument, it’s trivial to get access to the MongoDB database to start working with it right away!

Performing CRUD Operations on the MongoDB Testcontainer

Now that we have our MongoDB Testcontainer set up and we have a MongoClient connected to it, we can start performing CRUD operations on it. The connection details provided by the container instance made it a breeze to combine these two things, and truly we can focus on just the MongoDB.Driver method calls for CRUD.

Here’s an example of performing a simple CRUD operation:

// using code from earlier examples...

// Create
await collection.InsertOneAsync(new BsonDocument()
{
    ["Name"] = "Nick Cosentino",
});

// Read
var filterBuilder = Builders<BsonDocument>.Filter;
var filter = filterBuilder.Eq("Name", "Nick Cosentino");
var results = collection.Find(filter);

// Update
var updateBuilder = Builders<BsonDocument>.Update;
var update = updateBuilder.Set("Name", "Dev Leader");
collection.UpdateOne(filter, update);

// Delete
filter = filterBuilder.Eq("Name", "Dev Leader");
collection.DeleteOne(filter);

Using the previous code snippets, we were already up and running with our MongoDB container instance and a MongoClient. As a result, you can see in the code snippet above that we can directly work with our IMongoCollection<BsonDocument> that we obtained from the prior setup. This helps illustrate that once you have the MongoDB docker container up and running via Testcontainers, you don’t have to treat things any special way once you connect to it!


Wrapping Up C# Testcontainers for MongoDB

To conclude, C# Testcontainers for MongoDB is an incredibly simple way to get a transient MongoDB data store up and running for your testing and development. While this article didn’t focus on specific use cases, hopefully you have a better understanding of how transparent it feels to layer a MongoDB driver on top of Testcontainers to interact with MongoDB. Given that C# Testcontainers takes the headache out of setup, teardown, and even connection string management, it’s an easy recommendation from me if you want to get up and running with MongoDB for local usage.

If you found this useful and you’re looking for more learning opportunities, consider subscribing to my free weekly software engineering newsletter and check out my free videos on YouTube! Meet other like-minded software engineers and join my Discord community!


Want More Dev Leader Content?

  • Follow along on this platform if you haven’t already!

  • Subscribe to my free weekly software engineering and dotnet-focused newsletter. I include exclusive articles and early access to videos:
    SUBSCRIBE FOR FREE

  • Looking for courses? Check out my offerings:
    VIEW COURSES

  • E-Books & other resources:
    VIEW RESOURCES

  • Watch hundreds of full-length videos on my YouTube channel:
    VISIT CHANNEL

  • Visit my website for hundreds of articles on various software engineering topics (including code snippets):
    VISIT WEBSITE

  • Check out the repository with many code examples from my articles and videos on GitHub:
    VIEW REPOSITORY

0
Subscribe to my newsletter

Read articles from Dev Leader directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Dev Leader
Dev Leader

I'm a software engineering professional with over a decade of hands-on experience creating software and managing engineering teams. I graduated from the University of Waterloo in Honours Computer Engineering in 2012. I started blogging at https://www.devleader.ca in order to share my experiences about leadership, managing engineers, and 20+ years of programming. I'm the author of Dev Leader Weekly, which you can find here: https://devleaderweekly.substack.com And I create YouTube videos here: https://www.youtube.com/@DevLeader