-
Couldn't load subscription status.
- Fork 57
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 outCosmos 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)