Skip to content

MongoDB Atlas Local

MongoDB Atlas Local runs a local Atlas deployment in a single container. In addition to MongoDB, it runs the Atlas Search process, so you can test Atlas Search and Atlas Vector Search without an Atlas cluster.

Add the following dependency to your project file:

NuGet
1
dotnet add package Testcontainers.MongoDbAtlasLocal

You can start a MongoDB Atlas Local container instance from any .NET application. Here, we create different container instances and pass them to the base test class. This allows us to test different configurations.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
[UsedImplicitly]
public sealed class MongoDbAtlasLocalDefaultConfiguration : MongoDbAtlasLocalContainerTest
{
    public MongoDbAtlasLocalDefaultConfiguration()
        : base(new MongoDbAtlasLocalBuilder(TestSession.GetImageFromDockerfile()).Build())
    {
    }
}

[UsedImplicitly]
public sealed class MongoDbAtlasLocalNoAuthConfiguration : MongoDbAtlasLocalContainerTest
{
    public MongoDbAtlasLocalNoAuthConfiguration()
        : base(new MongoDbAtlasLocalBuilder(TestSession.GetImageFromDockerfile()).WithUsername(string.Empty).WithPassword(string.Empty).Build())
    {
    }
}

This example uses xUnit.net's IAsyncLifetime interface to manage the lifecycle of the container. The container is started in the InitializeAsync method before the test method runs, ensuring that the environment is ready for testing. After the test completes, the container is removed in the DisposeAsync method.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public async ValueTask InitializeAsync()
{
    await _mongoDbAtlasLocalContainer.StartAsync()
        .ConfigureAwait(false);
}

public async ValueTask DisposeAsync()
{
    await DisposeAsyncCore()
        .ConfigureAwait(false);

    GC.SuppressFinalize(this);
}

[Fact]
[Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))]
public void ConnectionStateReturnsOpen()
{
    // Given
    using var client = new MongoClient(_mongoDbAtlasLocalContainer.GetConnectionString());

    // When
    using var databases = client.ListDatabases(TestContext.Current.CancellationToken);

    // Then
    Assert.Contains(databases.ToEnumerable(TestContext.Current.CancellationToken), database => database.TryGetValue("name", out var name) && "admin".Equals(name.AsString));
    Assert.Equal(_mongoDbAtlasLocalContainer.GetConnectionString(), _mongoDbAtlasLocalContainer.GetConnectionString(ConnectionMode.Host));
}

[Fact]
[Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))]
public async Task CreateSearchIndexReturnsIndexName()
{
    // Given
    const string indexName = "default";

    using var client = new MongoClient(_mongoDbAtlasLocalContainer.GetConnectionString());

    var database = client.GetDatabase("test");

    await database.CreateCollectionAsync("movies", cancellationToken: TestContext.Current.CancellationToken)
        .ConfigureAwait(true);

    var collection = database.GetCollection<BsonDocument>("movies");

    var searchIndex = new CreateSearchIndexModel(indexName, new BsonDocument("mappings", new BsonDocument("dynamic", true)));

    // When
    var name = await collection.SearchIndexes.CreateOneAsync(searchIndex, TestContext.Current.CancellationToken)
        .ConfigureAwait(true);

    // Then
    Assert.Equal(indexName, name);
}

[Fact]
[Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))]
public async Task ExecScriptReturnsSuccessful()
{
    // Given
    const string scriptContent = "printjson(db.adminCommand({listDatabases:1,nameOnly:true,filter:{\"name\":/^admin/}}));";

    // When
    var execResult = await _mongoDbAtlasLocalContainer.ExecScriptAsync(scriptContent, TestContext.Current.CancellationToken)
        .ConfigureAwait(true);

    // Then
    Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
    Assert.Empty(execResult.Stderr);
}

The test example creates an Atlas Search index. Use GetConnectionString() to configure the MongoDB client. The default configuration creates the root user mongo with the password mongo. Use WithUsername(string) and WithPassword(string) to configure different credentials, or set both to an empty string to disable authentication.

The test example uses the following NuGet dependencies:

1
2
3
4
5
<PackageReference Include="Microsoft.NET.Test.Sdk"/>
<PackageReference Include="coverlet.collector"/>
<PackageReference Include="xunit.runner.visualstudio"/>
<PackageReference Include="xunit.v3"/>
<PackageReference Include="MongoDB.Driver"/>

To execute the tests, use the command dotnet test from a terminal.

Tip

For the complete source code of this example and additional information, please refer to our test projects.

Init scripts

Use WithInitScript(string) or WithInitScriptContent(string, string) to seed the deployment on its first start. JavaScript (.js) scripts run in mongosh against the database set with WithInitDatabase(string), which defaults to test. Shell (.sh) scripts run in bash. The scripts run in alphabetical order of their file names before the container is ready:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[UsedImplicitly]
public sealed class MongoDbAtlasLocalInitScriptConfiguration : MongoDbAtlasLocalContainerTest
{
    public MongoDbAtlasLocalInitScriptConfiguration()
        : base(new MongoDbAtlasLocalBuilder(TestSession.GetImageFromDockerfile()).WithInitDatabase("sample_mflix").WithInitScriptContent("01-movies.js", "db.movies.insertOne({title:\"The Matrix\"});").Build())
    {
    }

    [Fact]
    [Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))]
    public async Task FindReturnsSeededDocument()
    {
        // Given
        using var client = new MongoClient(_mongoDbAtlasLocalContainer.GetConnectionString());

        var collection = client.GetDatabase("sample_mflix").GetCollection<BsonDocument>("movies");

        // When
        var movie = await collection.Find(FilterDefinition<BsonDocument>.Empty).SingleAsync(TestContext.Current.CancellationToken)
            .ConfigureAwait(true);

        // Then
        Assert.Equal("The Matrix", movie["title"].AsString);
    }
}

A restarted or reused container keeps its data and does not run the init scripts again.