This article shows how integration tests could be implemented for an ASP.NET Core application which uses EF Core and Azure Cosmos. The database tests can be run locally or in an Azure DevOps build using the Azure Cosmos emulator. XUnit is used to implement the tests.

Code: https://github.com/damienbod/AspNetCoreEfCoreCosmosTesting

EF Core is used to the access Azure Cosmos database. An EF Core **DbContext **was created to access Cosmos. This is like any EF Core context, with the **DBSet **definitions as required. Some Cosmos specific definitions are added using the **OnModelCreating **method. See the Cosmos-specific model customization for more details.

public class CosmosContext : DbContext

{

public CosmosContext(DbContextOptions<CosmosContext> options)

: base(options) { }

public DbSet<MyData> MyData { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

modelBuilder.HasDefaultContainer(``"MyDataStore"``);

modelBuilder.Entity<MyData>()

.ToContainer(``"MyDataItems"``);

modelBuilder.Entity<MyData>()

.HasPartitionKey(o => o.PartitionKey);

modelBuilder.Entity<MyData>()

.Property(d => d.ETag)

.IsETagConcurrency();

}

}

The **MyData **class is is used to model the Cosmos documents. This has a **PartitionKey **and also an **ETag **which can be used for the Optimistic concurrency validation.

1

2

3

4

5

6

7

8

public class MyData

{

public string Id { get; set; }

public string PartitionKey { get; set; }

public string Name { get; set; }

public string Description { get; set; }

public string ETag { get; set; }

}

The **MyDataService **service class is used to access the context and implement some query logic as required. I like to keep this simple and not separate the specification of the queries from the the business or the Linq statements. This reduces the amount of code and keeps the data access, business simple and makes it easy to adapt.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

public class MyDataService

{

private CosmosContext _cosmosContext;

public MyDataService(CosmosContext cosmosContext)

{

_cosmosContext = cosmosContext;

}

public void EnsureCreated()

{

_cosmosContext.Database.EnsureCreated();

}

public async Task CreateAsync(MyData myData)

{

await _cosmosContext.MyData.AddAsync(myData);

await _cosmosContext.SaveChangesAsync(false);

}

public async Task<MyData> Get(string id)

{

return await _cosmosContext.MyData.FirstAsync(d => d.Id == id);

}

public async Task<IList<MyData>> NameContains(string name)

{

return await _cosmosContext.MyData

.Where(d => d.Name.Contains(name)).ToListAsync();

}

}

The **ConfigureServices **method adds the services required to use EF Core and Cosmos DB. The services are used in a Razor page application, but this could be any web application, ASP.NET Core API or ASP.NET Core Blazor.

1

2

3

4

5

6

7

8

9

10

11

12

13

public void ConfigureServices(IServiceCollection services)

{

services.AddDbContext<CosmosContext>(options =>

{

options.UseCosmos(

"AccountEndpoint=[https://localhost:8081/;AccountKey=C2y6yDjf5/R](https://localhost:8081/;AccountKey=C2y6yDjf5/R)+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="``,

databaseName: "MyDataDb"

);

});

services.AddScoped<MyDataService>();

services.AddRazorPages();

}

The service needs to be tested. Instead of mocking away the database or using separate specifications classes as parameters, the service can be tested as one using Azure Cosmos emulator and EF Core. We used the framework tools to test our code. An EF Core in-memory database could also be used instead of the Azure Cosmos emulator. We use the emulator for these tests.

#.net core #asp.net core #web #azure #azure devops #asp.net

Integration Testing for ASP.NET Core using EF Core Cosmos with XUnit and Azure DevOps
2.35 GEEK