Let's imagine that you have modern application project made in times of .NET core 6 release. Needless to say, it's structure is a little bit different from older .net versions (where you had 2 separate files - Startup.cs and Program.cs)
Let's dive through old and new structure differences, that would be useful for further explanations
.NET Core 5 Times Project structure
Startup.cs
Here we used to register all services, configs and classes.
In fact, this is a starting point of application. Here, for example, I added few lines of code for creating scope for Entity Context and running initial database migrations.
Both old files Program.cs and Startup.cs are now merged together into Program.cs file, and there are not any classes inside anymore. Only pure functions for adding new modifications.
Typical code of Program.cs .NET Core 6+ project
var builder = WebApplication.CreateBuilder(args);//...builder.Services.AddControllers();// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbucklebuilder.Services.AddEndpointsApiExplorer();builder.Services.AddSwaggerGen();var app = builder.Build();//...if(app.Environment.IsDevelopment()){ app.UseSwagger(); app.UseSwaggerUI();}app.UseAuthorization();
.NET Core 5 vs 6 structure - Advantages and disadvantages (+ solving problems)
Advantages
1 simple file instead of 2
less class wrappings - more simple and clean code
new webApplicationBuilder was presented
Disadvantages
We don't have any classes in program to make relations. For example, for adding such libs as Mediator or FluentValidation you need to get assembly type by name, example:
One of possible solutions is adding this line to the end of file Program.csz:
// Make the implicit Program class public so test projects can access itpublicpartialclassProgram{}
Now, you can use structures like typeof(Program) or WebApplicationFactory<Program> (while doing testing stuff)
Configuring .NET Core 5 Test server
Here we have nu-get package called Microsoft.TestPlatform.TestHost with Microsoft.AspNetCore.TestHost.
Here is TestServerFixture from one of my projects, that relates to Program from real application:
publicclassTestServerFixture:IDisposable{privatereadonlyTestServer _testServer;publicHttpClient Client {get;}publicTestServerFixture(){var builder =newWebHostBuilder()// .UseContentRoot(GetContentRootPath()).UseEnvironment("Development").UseConfiguration(FakeConfiguration.GetInstance()).UseStartup<Startup>();// Uses Start up class from your API Host project to configure the test server _testServer =newTestServer(builder); Client = _testServer.CreateClient();}// ...}
Unit test for controllers and utils is good method, but I also prefer to have real running instance of application for my tests, with ability to send real POST and GET request.
So, lot's of people in internet starting to build another separate configuration for running such testing virtual node, but in fact we have all necessary configurations in our Program.cs file. Let's use it! But we need to make some changes in it, for example - to use not real physical database, but memory one.
First thing first, now we can relate to class Program.cs and use it in combination with WebApplicationFactory class: