-
Notifications
You must be signed in to change notification settings - Fork 56
Using Cosmos DB databases
If you are testing Cosmos DB, then the Azure Cosmos DB Emulator is a great tool to use. It runs locally on the development system and allows you to test Cosmos DB queries without paying for a Cosmos DB database on Azure.
Here is an example of using the CreateUniqueClassCosmosDbEmulator<T>
method, which takes the class as the name of the database.
public async Task TestAddCosmosBookWithReviewsOk()
{
//SETUP
var options = this.CreateUniqueClassCosmosDbEmulator<CosmosDbContext>();
using var context = new CosmosDbContext(options);
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
//ATTEMPT
var cBook = new CosmosBook
{
CosmosBookId = 1,
Title = "Book Title",
PublishedDate = new DateTime(2019, 1,1),
};
context.Add(cBook);
await context.SaveChangesAsync();
//VERIFY
await context.Books.FindAsync(1).ShouldNotBeNull();
}
_NOTE: Cosmos DB only provides async methods to access its database so you must use EF Core async methods, otherwise you may have some problems - see EF Core Cosmos DB limitations.
All the previous extension methods have an optional parameter that allows you to set extra options at the DbContextOptionsBuilder<T>
level. Below is part of the unit tests showing how to add/override options.
//... previous code removed to focus on the feature
var options = this.CreateUniqueClassCosmosDbEmulator<BookContext>(
builder => builder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)); //sets a tracking behavior
using (var context = new BookContext(options))
{
//VERIFY
var book = context.Books.First();
context.Entry(book).State.ShouldEqual(EntityState.Detached);
}
This returns a Cosmos DB options with the connection string from the appsettings.json
file but the name of the database now has the type name of the object (which should be this
) followed by the method name as a suffix. See test code below
[Fact]
public void TestSqlServerUniqueMethodOk()
{
var options = this.CreateUniqueMethodCosmosDbEmulator<EfCoreContext>();
using var context = new EfCoreContext(options))
//... other parts left out
}
NOTE: You shouldn't really need the CreateUniqueMethodOptions<T>
method, as xUnit runs the methods inside a test class serially, so CreateUniqueClassOptions<T>
should be enough to avoid parallel unit tests accessing the same database.
Its often useful to see what EF Core is doing when something isn't working properly. The `CreateUniqueMethodCosmosDbEmulatorWithLogTo method returns the logs. Below is a simple version that captures the logs into a list, but more complex options are possible - see Tools for capturing EF Core logging for more details.
var logs = new List<string>();
var options = this.CreateUniqueMethodCosmosDbEmulatorWithLogTo<BookContext>(log => logs.Add(log));
using var context = new BookContext(options);
//... rest of test left out
Cosmos DB database are quick to create / delete because they don't have relationships etc., so best way (and only way) is to call EnsureDeletedAsync
followed by EnsureCreatedAsync
- see the code below
var options = this.CreateUniqueClassCosmosDbEmulator<CosmosDbContext>();
using var context = new CosmosDbContext(options);
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
- Testing against a PostgreSQL db
- Changes in EfCore.TestSupport 5
- Testing with production data
- Using an in-memory database (old)