{"id":47730682,"url":"https://github.com/lemonlion/cosmosdb.inmemoryemulator","last_synced_at":"2026-04-16T10:02:50.245Z","repository":{"id":348126819,"uuid":"1196110482","full_name":"lemonlion/CosmosDB.InMemoryEmulator","owner":"lemonlion","description":"An In-Process Emulator For CosmosDB To Be Used For Integration/Component Testing","archived":false,"fork":false,"pushed_at":"2026-04-04T15:53:15.000Z","size":2013,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-04T23:18:41.651Z","etag":null,"topics":["acceptance-testing","component-testing","cosmos","cosmos-db","cosmos-sdk","cosmosdb","emulator","fake","integration-testing","mock","testing-tools"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lemonlion.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-30T11:35:35.000Z","updated_at":"2026-04-04T15:53:20.000Z","dependencies_parsed_at":"2026-04-04T23:00:38.510Z","dependency_job_id":null,"html_url":"https://github.com/lemonlion/CosmosDB.InMemoryEmulator","commit_stats":null,"previous_names":["lemonlion/cosmosdb.inmemoryemulator"],"tags_count":76,"template":false,"template_full_name":null,"purl":"pkg:github/lemonlion/CosmosDB.InMemoryEmulator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemonlion%2FCosmosDB.InMemoryEmulator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemonlion%2FCosmosDB.InMemoryEmulator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemonlion%2FCosmosDB.InMemoryEmulator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemonlion%2FCosmosDB.InMemoryEmulator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lemonlion","download_url":"https://codeload.github.com/lemonlion/CosmosDB.InMemoryEmulator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemonlion%2FCosmosDB.InMemoryEmulator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31454200,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T21:22:52.476Z","status":"ssl_error","status_checked_at":"2026-04-05T21:22:51.943Z","response_time":75,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["acceptance-testing","component-testing","cosmos","cosmos-db","cosmos-sdk","cosmosdb","emulator","fake","integration-testing","mock","testing-tools"],"created_at":"2026-04-02T21:27:11.893Z","updated_at":"2026-04-16T10:02:50.240Z","avatar_url":"https://github.com/lemonlion.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CosmosDB.InMemoryEmulator\n\n[![NuGet](https://img.shields.io/nuget/v/CosmosDB.InMemoryEmulator.svg)](https://www.nuget.org/packages/CosmosDB.InMemoryEmulator)\n[![NuGet Downloads](https://img.shields.io/nuget/dt/CosmosDB.InMemoryEmulator.svg)](https://www.nuget.org/packages/CosmosDB.InMemoryEmulator)\n[![CI](https://github.com/lemonlion/CosmosDB.InMemoryEmulator/actions/workflows/ci.yml/badge.svg)](https://github.com/lemonlion/CosmosDB.InMemoryEmulator/actions/workflows/ci.yml)\n\nA fully featured, in-process, fake for Azure Cosmos DB SDK for .NET — purpose-built for fast, reliable component and integration testing.  Runs in memory on the fly for the lifetime of your test run (although persistence between runs is available as a feature).\n\nHas full support for *all* Cosmos CRUD and SQL querying, including raw querying, functions, LINQ querying (including `GetItemLinqQueryable\u003cT\u003e()` with `.ToFeedIterator()` support - no production code changes necessary).\n\nIncludes all the other features of CosmosDB like Triggers, Stored Procedures, Change Feed, Transactional Batches, Bulk Operations, Point-in-time restore, TTL...\n\nClient encryption keys are deliberately not implemented as they require Azure Key Vault integration and are out of scope for a testing fake.\n\n## Usage\n\nWorks by replacing either `Microsoft.Azure.Cosmos.Container` or `Microsoft.Azure.Cosmos.CosmosClient`.\n\n### Dependency Injection\n\nIn your `ConfigureTestServices()` method in your `WebApplicationFactory()`:\n\n```csharp\nserviceCollection.UseInMemoryCosmosDB(); // Replaces all Cosmos Clients and Containers — highest fidelity, zero production code changes\n```\nOR\n```csharp\nserviceCollection.UseInMemoryCosmosContainers(); // Replaces only Cosmos Containers (lower fidelity, needs .ToFeedIteratorOverridable() for LINQ)\n```\n\n### Direct Instantiation\n\nIdeal with highest fidelity:\n\n```csharp\n// 1. Create an InMemoryContainer as the backing store\nvar container = new InMemoryContainer(\"my-container\", \"/partitionKey\");\n\n// 2. Wire up FakeCosmosHandler → CosmosClient\nusing var handler = new FakeCosmosHandler(container);\nusing var client = new CosmosClient(\n    \"AccountEndpoint=https://localhost:9999/;AccountKey=dGVzdGtleQ==;\",\n    new CosmosClientOptions\n    {\n        ConnectionMode = ConnectionMode.Gateway,\n        LimitToEndpoint = true,\n        HttpClientFactory = () =\u003e new HttpClient(handler)\n    });\n\n// 3. Use the real SDK — all calls are intercepted by the handler\nvar cosmosContainer = client.GetContainer(\"db\", \"my-container\");\n```\n\nAlternatively - the following to are slightly more limited usages, but still fully functional.\nThey require the use of `.ToFeedIteratorOverrideable()` wherever `.ToFeedIterator()` is used, \nand have some minor differences (e.g. use of LINQ to objects for querying) - [see here for more details](https://github.com/lemonlion/CosmosDB.InMemoryEmulator/wiki/Integration-Approaches).\n\n```csharp\nvar cosmosClient = new InMemoryCosmosClient();\n```\nOR\n```csharp\nvar cosmosContainer = new InMemoryContainer();\n```\n\n## Motivation\n\nDesigned for super fast feedback from your Integration/Component tests in a local or CI environment, to avoid relying completely on the official Cosmos emulator or official Cosmos DB or inaccurate high level abstractions. \n\n| Traditional Approach | Problem |\n|----------|---------|\n| **[Official Cosmos DB Emulator](https://learn.microsoft.com/en-us/azure/cosmos-db/emulator)** | Heavy process, slow startup, poor performance, limited feature set, unreliable in CI |\n| **Real Azure Cosmos DB** | Slower, costly, requires network, authentication overhead, shared state between test runs |\n| **Repository Abstraction Layer** | Fragile, doesn't test query logic, misses serialization bugs |\n\nRecommendation is to use **CosmosDB.InMemoryEmulator** for integration/component testing locally and in CI for quick feedback and iteration, while still having the integration/component tests *additionally* running in CI against the official out of process emulator for (10x) slower feedback.\n\nSee the **[Feature Comparison With Alternatives](https://github.com/lemonlion/CosmosDB.InMemoryEmulator/wiki/Feature-Comparison-With-Alternatives)** for a detailed side-by-side breakdown.\n\n## Features\n\n- **Full CRUD** — typed and stream variants with proper status codes and ETags\n- **Feature Complete SQL query engine** — 125+ built-in functions, `SELECT`, `WHERE`, `ORDER BY`, `GROUP BY`, `HAVING`, `JOIN`, `TOP`, `DISTINCT`, `OFFSET/LIMIT`, subqueries, full-text search, vector search\n- **Full LINQ support** — `GetItemLinqQueryable\u003cT\u003e()` with `.ToFeedIterator()` interception\n- **Triggers** — pre-trigger and post-trigger execution via C# handlers, with optional JavaScript body interpretation via the `CosmosDB.InMemoryEmulator.JsTriggers` package\n- **Bulk operations** — `AllowBulkExecution = true` with concurrent `Task.WhenAll` patterns\n- **Transactional batches** — atomic execution with rollback on failure\n- **Change feed** — iterators, checkpoints, delete tombstones, `ChangeFeedProcessor`, and manual checkpoint processor\n- **Point-in-time restore** — restore a container to any previous point in time via change feed replay\n- **Partition keys** — single and composite, auto-extraction from documents\n- **State persistence** — export/import container state as JSON; automatic save/restore between test runs via `StatePersistenceDirectory`\n- **TTL / expiration** — container-level and per-item with lazy eviction\n- **ETag / optimistic concurrency** — `IfMatchEtag`, `IfNoneMatchEtag`, wildcard `*`\n- **System metadata** — `_ts` and `_etag` injected into stored items, matching real Cosmos DB\n- **Patch operations** — all 6 types with deep nested paths and filter predicates\n- **Fault injection** — simulate 429 throttling, 503 errors, timeouts\n- **DI integration** — `UseInMemoryCosmosDB()` extension methods for `IServiceCollection`\n- **HTTP-level interception** — `FakeCosmosHandler` for zero-code-change integration\n- **Custom handler wrapping** — insert `DelegatingHandler` middleware (logging, tracking, metrics) via `HttpMessageHandlerWrapper`\n- **Unique key policies** — constraint enforcement on Create, Upsert, Replace, and Patch (typed and stream)\n- **FeedRange support** — configurable `FeedRangeCount` with scoped queries and change feed iterators\n- **Vector search** — `VECTORDISTANCE` with cosine, dot product, and Euclidean distance; works in `SELECT`, `WHERE`, and `ORDER BY`\n- **Users \u0026 permissions** — stub user/permission CRUD with synthetic tokens (no authorization enforced)\n- **Computed properties** — virtual container-level properties evaluated at query time; usable in `SELECT`, `WHERE`, `ORDER BY`, `GROUP BY`, `DISTINCT`, `HAVING`, with aliases, aggregates, and all expression types\n- **7500+ tests** covering all features and performance, ensuring feature consistency and parity with real CosmosDB\n\nFor the full feature list see [Features](https://github.com/lemonlion/CosmosDB.InMemoryEmulator/wiki/Features). For a side-by-side comparison with the official Microsoft emulator see [Feature Comparison With Alternatives](https://github.com/lemonlion/CosmosDB.InMemoryEmulator/wiki/Feature-Comparison-With-Alternatives). For behavioural differences from a real CosmosDB see [Known Limitations](https://github.com/lemonlion/CosmosDB.InMemoryEmulator/wiki/Known-Limitations)\n\n## NuGet Packages\n\n| Framework | Package | Description | NuGet |\n|---|---|---|---|\n| **Core library** | `CosmosDB.InMemoryEmulator` | Primary Features | [![NuGet Version](https://img.shields.io/nuget/v/CosmosDB.InMemoryEmulator)](https://www.nuget.org/packages/CosmosDB.InMemoryEmulator) |\n| **JavaScript Triggers** | `CosmosDB.InMemoryEmulator.JsTriggers` | Support for JS Triggers | [![NuGet Version](https://img.shields.io/nuget/v/CosmosDB.InMemoryEmulator)](https://www.nuget.org/packages/CosmosDB.InMemoryEmulator.JsTriggers) |\n| **Production Extensions** | `CosmosDB.InMemoryEmulator.ProductionExtensions` | Support for use of the *optional* `.ToFeedIteratorOverridable()` alternative to the native `.ToFeedIterator()`* | [![NuGet Version](https://img.shields.io/nuget/v/CosmosDB.InMemoryEmulator)](https://www.nuget.org/packages/CosmosDB.InMemoryEmulator.ProductionExtensions) |\n\n* Native `.ToFeedIterator()` method works without any problems, there are just occasionally some advantages to using `.ToFeedIteratorOverridable()`, hence why this optional package is supplied.  See [Feed Iterator Usage](https://github.com/lemonlion/CosmosDB.InMemoryEmulator/wiki/Feed-Iterator-Usage-Guide).\n\n## Documentation\n\nFull documentation is available on the **[Wiki](https://github.com/lemonlion/CosmosDB.InMemoryEmulator/wiki)**.\n\n## Dependencies\n\n| Package | Purpose |\n|---------|---------|\n| [Microsoft.Azure.Cosmos](https://www.nuget.org/packages/Microsoft.Azure.Cosmos) | Azure Cosmos DB SDK |\n| [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json) | JSON serialization |\n| [NSubstitute](https://www.nuget.org/packages/NSubstitute) | Internal mocking for SDK response types |\n| [Superpower](https://www.nuget.org/packages/Superpower) | Parser combinators for SQL engine |\n\n## License\n\n[MIT License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flemonlion%2Fcosmosdb.inmemoryemulator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flemonlion%2Fcosmosdb.inmemoryemulator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flemonlion%2Fcosmosdb.inmemoryemulator/lists"}