FakeCosmosDb 0.0.3
See the version list below for details.
dotnet add package FakeCosmosDb --version 0.0.3
NuGet\Install-Package FakeCosmosDb -Version 0.0.3
<PackageReference Include="FakeCosmosDb" Version="0.0.3" />
<PackageVersion Include="FakeCosmosDb" Version="0.0.3" />
<PackageReference Include="FakeCosmosDb" />
paket add FakeCosmosDb --version 0.0.3
#r "nuget: FakeCosmosDb, 0.0.3"
#addin nuget:?package=FakeCosmosDb&version=0.0.3
#tool nuget:?package=FakeCosmosDb&version=0.0.3
Tim Abell FakeCosmosDb
This library provides an in-memory CosmosDB fake for unit testing, with optional support for running tests against the real CosmosDB Emulator.
Features
✅ Supports SQL-like queries (SELECT * FROM c WHERE c.Name = 'Alice'
)
✅ Fully in-memory, no dependencies required
✅ Multi-container support
✅ Can switch between fake mode and real CosmosDB mode
✅ GitHub Actions CI/CD ready
✅ Efficient indexing for fast queries
✅ Support for pagination with continuation tokens
✅ Advanced query features like CONTAINS, STARTSWITH, and nested properties
✅ SELECT projections to return only specific fields
Installation
To use the in-memory CosmosDB fake, install via NuGet:
dotnet add package # TBC
Quick Start
// Create an instance of the fake
var cosmosDb = new FakeCosmosDb();
// Create a container
await cosmosDb.AddContainerAsync("Users");
// Add an item
await cosmosDb.AddItemAsync("Users", new {
id = "1",
Name = "Alice",
Email = "alice@example.com"
});
// Query items
var results = await cosmosDb.QueryAsync("Users", "SELECT * FROM c WHERE c.Name = 'Alice'");
// Use pagination
var (pageResults, continuationToken) = await cosmosDb.QueryWithPaginationAsync(
"Users",
"SELECT * FROM c",
maxItemCount: 10
);
// Get the next page using the continuation token
var (nextPageResults, nextContinuationToken) = await cosmosDb.QueryWithPaginationAsync(
"Users",
"SELECT * FROM c",
maxItemCount: 10,
continuationToken: continuationToken
);
Advanced Queries
The fake supports a wide range of CosmosDB SQL query features:
Basic Filtering
// Equality
var results = await cosmosDb.QueryAsync("Users", "SELECT * FROM c WHERE c.Name = 'Alice'");
// Numeric comparisons
var results = await cosmosDb.QueryAsync("Users", "SELECT * FROM c WHERE c.Age > 30");
// String functions
var results = await cosmosDb.QueryAsync("Users", "SELECT * FROM c WHERE CONTAINS(c.Name, 'Ali')");
var results = await cosmosDb.QueryAsync("Users", "SELECT * FROM c WHERE STARTSWITH(c.Email, 'alice')");
Projections
// Select specific fields
var results = await cosmosDb.QueryAsync("Users", "SELECT c.Name, c.Email FROM c");
// Select nested properties
var results = await cosmosDb.QueryAsync("Users", "SELECT c.Name, c.Address.City FROM c");
Ordering and Limiting
// Order by a field
var results = await cosmosDb.QueryAsync("Users", "SELECT * FROM c ORDER BY c.Name");
// Limit results
var results = await cosmosDb.QueryAsync("Users", "SELECT * FROM c LIMIT 10");
Testing with xUnit
Using the Fake in Tests
public class UserServiceTests
{
private readonly ICosmosDb _db;
private readonly UserService _userService;
public UserServiceTests()
{
_db = new FakeCosmosDb();
_db.AddContainerAsync("Users").Wait();
// Inject the fake into your service
_userService = new UserService(_db);
}
[Fact]
public async Task GetUserByName_ReturnsCorrectUser()
{
// Arrange
await _db.AddItemAsync("Users", new { id = "1", Name = "Alice" });
// Act
var user = await _userService.GetUserByNameAsync("Alice");
// Assert
Assert.Equal("Alice", user.Name);
}
}
Testing with Both Fake and Real CosmosDB
You can run the same tests against both the in-memory fake and the real CosmosDB emulator:
public class CosmosDbTests
{
public static IEnumerable<object[]> TestConfigurations()
{
yield return new object[] { new FakeCosmosDb() };
yield return new object[] { new CosmosDbAdapter("AccountEndpoint=https://localhost:8081;AccountKey=your-key;") };
}
[Theory]
[MemberData(nameof(TestConfigurations))]
public async Task Can_Insert_And_Query_Item(ICosmosDb db)
{
var containerName = "TestContainer";
await db.AddContainerAsync(containerName);
var user = new { id = "1", Name = "Alice", Age = 30 };
await db.AddItemAsync(containerName, user);
var results = await db.QueryAsync(containerName, "SELECT * FROM c WHERE c.Name = 'Alice'");
Assert.Single(results);
Assert.Equal("Alice", results.First()["Name"]);
}
}
Running Tests with the Real CosmosDB Emulator
To run tests against a real CosmosDB Emulator, start the emulator in Docker:
docker run -p 8081:8081 -d mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator
Then, run the tests:
dotnet test
Using with Dependency Injection
public void ConfigureServices(IServiceCollection services)
{
// For local development and testing
if (Environment.IsDevelopment())
{
var cosmosDb = new FakeCosmosDb();
cosmosDb.AddContainerAsync("Users").Wait();
services.AddSingleton<ICosmosDb>(cosmosDb);
}
else
{
// For production, use the real CosmosDB
services.AddSingleton<ICosmosDb>(sp =>
new CosmosDbAdapter(Configuration.GetConnectionString("CosmosDb")));
}
// Register your services that depend on ICosmosDb
services.AddScoped<IUserRepository, UserRepository>();
}
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Azure.Identity (>= 1.13.2)
- Microsoft.Azure.Cosmos (>= 3.47.2)
- Microsoft.Extensions.Logging.Abstractions (>= 7.0.1)
- Newtonsoft.Json (>= 13.0.3)
- Sprache (>= 2.3.1)
- System.Linq.Dynamic.Core (>= 1.3.7)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.