Testcontainers NoSQL 整合測試完整指南。當需要對 MongoDB 或 Redis 進行容器化整合測試時使用。涵蓋 MongoDB 文件操作、Redis 五種資料結構、Collection Fixture 模式。包含 BSON 序列化、索引效能測試、資料隔離策略與容器生命週期管理。 Make sure to use this skill whenever the user mentions Testcontainers MongoDB, Testcontainers Redis, NoSQL integration test, BSON serialization, or Redis data structure testing, even if they don't explicitly ask for NoSQL container testing. Keywords: testcontainers mongodb, testcontainers redis, mongodb integration test, redis integration test, nosql testing, MongoDbContainer, RedisContainer, IMongoDatabase, IConnectionMultiplexer, BSON serialization, BsonDocument, 文件模型測試, 快取測試, Collection Fixture
NoSQL 資料庫測試與關聯式資料庫有顯著差異:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<!-- MongoDB 相關套件 -->
<PackageReference Include="MongoDB.Driver" Version="3.7.1" />
<PackageReference Include="MongoDB.Bson" Version="3.7.1" />
<!-- Redis 相關套件 -->
<PackageReference Include="StackExchange.Redis" Version="2.12.8" />
<!-- Testcontainers -->
<PackageReference Include="Testcontainers" Version="4.11.0" />
<PackageReference Include="Testcontainers.MongoDb" Version="4.11.0" />
<PackageReference Include="Testcontainers.Redis" Version="4.11.0" />
<!-- 測試框架 -->
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageReference Include="AwesomeAssertions" Version="9.4.0" />
<!-- JSON 序列化與時間測試 -->
<PackageReference Include="System.Text.Json" Version="10.0.5" />
<PackageReference Include="Microsoft.Bcl.TimeProvider" Version="10.0.5" />
<PackageReference Include="Microsoft.Extensions.TimeProvider.Testing" Version="10.4.0" />
</ItemGroup>
</Project>
| 套件 | 版本 | 用途 |
|---|---|---|
| MongoDB.Driver | 3.7.1 | MongoDB 官方驅動程式,支援最新功能 |
| MongoDB.Bson | 3.7.1 | BSON 序列化處理 |
| StackExchange.Redis | 2.12.8 | Redis 客戶端,支援 Redis 7.x |
| Testcontainers.MongoDb | 4.11.0 | MongoDB 容器管理 |
| Testcontainers.Redis | 4.11.0 | Redis 容器管理 |
涵蓋 MongoDB Container Fixture 建立、複雜文件模型設計(巢狀物件、陣列、字典)、BSON 序列化測試、CRUD 操作測試(含樂觀鎖定)以及索引效能與唯一性約束測試。使用 Collection Fixture 模式共享容器,節省 80% 以上的測試時間。
完整程式碼範例請參考 MongoDB 容器化測試詳細指南
涵蓋 Redis Container Fixture 建立、快取模型設計(CacheItem 泛型包裝器、UserSession、RecentView、LeaderboardEntry)以及 Redis 五種資料結構(String、Hash、List、Set、Sorted Set)的完整測試範例,包含 TTL 過期測試與資料隔離策略。
完整程式碼範例請參考 Redis 容器化測試詳細指南
使用 Collection Fixture 共享容器,避免每個測試重啟容器:
// 定義集合
[CollectionDefinition("MongoDb Collection")]
public class MongoDbCollectionFixture : ICollectionFixture<MongoDbContainerFixture> { }
// 使用集合
[Collection("MongoDb Collection")]
public class MyMongoTests
{
public MyMongoTests(MongoDbContainerFixture fixture)
{
// 使用共享的容器
}
}
確保測試間不互相干擾:
// MongoDB:使用唯一的 Email/Username
var user = new UserDocument
{
Username = $"testuser_{Guid.NewGuid():N}",
Email = $"test_{Guid.NewGuid():N}@example.com"
};
// Redis:使用唯一的 Key 前綴
var testId = Guid.NewGuid().ToString("N")[..8];
var key = $"test:{testId}:mykey";
// MongoDB:測試後清理
await fixture.ClearDatabaseAsync();
// Redis:使用 KeyDelete 而非 FLUSHDB(避免權限問題)
var keys = server.Keys(database.Database);
if (keys.Any())
{
await database.KeyDeleteAsync(keys.ToArray());
}
| 策略 | 說明 |
|---|---|
| Collection Fixture | 容器只啟動一次,節省 80%+ 時間 |
| 資料隔離 | 使用唯一 Key/ID 而非清空資料庫 |
| 批次操作 | 使用 InsertManyAsync、SetMultipleStringAsync |
| 索引建立 | 在 Fixture 初始化時建立索引 |
某些 Redis 容器映像檔預設不啟用 admin 模式:
// ❌ 錯誤:可能失敗
await server.FlushDatabaseAsync();
// ✅ 正確:使用 KeyDelete
var keys = server.Keys(database.Database);
if (keys.Any())
{
await database.KeyDeleteAsync(keys.ToArray());
}
// 測試時使用唯一的 Email 避免衝突
var uniqueEmail = $"test_{Guid.NewGuid():N}@example.com";
// 增加等待時間
_container = new MongoDbBuilder()
.WithImage("mongo:7.0")
.WithWaitStrategy(Wait.ForUnixContainer()
.UntilCommandIsCompleted("mongosh --eval 'db.runCommand({ ping: 1 })'"))
.Build();
本技能內容提煉自「老派軟體工程師的測試修練 - 30 天挑戰」系列文章: