

TestServer & ASP.NET Core 5: Fix “System.InvalidOperationException : Soluti...
source link: https://anthonygiretti.com/2021/03/16/testserver-asp-net-core-5-fix-system-invalidoperationexception-solution-root-could-not-be-located-using-application-root-with-a-custom-startup-file/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Introduction
I am very happy to write this post today because I have had a lot of trouble over the last few days getting my integration tests with TestServer to work on ASP.NET Core 5. I usually use a dedicated Startup.cs file to my integration tests rather than using the web application’s one.The simple good reason is that I do not like to replace instances of services or other configuration, I prefer a dedicated file for that. With each version of ASP.NET Core comes a change in the behavior of integration tests and in this post I will show you how to fix the external “System.InvalidOperationException : Solution root could not be located using application root” error when we use a Startup.cs file dedicated to our integration tests.
What’s happening ?
WebApplicationFactory class needs to infer the content root path and it’s doing it wrong if you proceed like this with a custom Startup.cs file for your tests when you create your own web factory:
public class MyWebFactory<TestStartup> : WebApplicationFactory<TestStartup> { protected string ApplicationName;
protected override IWebHostBuilder CreateWebHostBuilder() { return WebHost.CreateDefaultBuilder(); }
protected override void ConfigureWebHost(IWebHostBuilder builder) { builder.UseContentRoot(".");
builder.ConfigureAppConfiguration((context, b) => { context.HostingEnvironment.ApplicationName = "YourApplicationAssemblyName"; // Required to infer the content root application to test });
base.ConfigureWebHost(builder); } }
This works perfectly with ASP.NET Core 3.1, but, with ASP.NET Core 5 you’ll run into that error: “System.InvalidOperationException : Solution root could not be located using application root”. TestServer confuses the integration test app and the web application.
To make it work with ASP.NET Core 5, you have to do 3 fixes:
- Go to you custom Startup.cs file in your integration test project and add the extension AddApplicationPart() on AddController() extension. This extension needs in parameter the application (to be tested) assembly to find all controllers and register them in the services collection. If you miss that step you’ll get 404 not found in your tests. Example:
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection;
namespace Calzolari.WebApi.Tests.Common { public class TestStartup { public TestStartup(IConfiguration configuration) { Configuration = configuration; }
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers().AddApplicationPart(typeof(Startup).Assembly); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
- In your custom web factory, override the CreateHostBuilder() method instead of CreateWebHostBuilder() like in ASP.NET Core 3.1, the latter doesn’t not run with ASP.NET Core 5, it allows to create a IHost instead of a IWebHost which is not recommended to be used anymore. Then add the extension method on the builder UseStartup<T>() and use your custom Startup.cs file as the EntryPoint of your integration test app.
- In the same custom web factory, when you inherit from WebApplicationFactory, instead passing as generic your custom Startup file, pass any class of your application to be tested. It is only used for reflection purpose (while the WebApplicationFactory tries to infer the application’s content root). Example:
using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting;
namespace Calzolari.WebApi.Tests.Common { public class MyWebFactory : WebApplicationFactory<Startup> { protected override IHostBuilder CreateHostBuilder() { return Host.CreateDefaultBuilder().ConfigureWebHost((builder) => { builder.UseStartup<TestStartup>(); }); } } }
If you now use your custom factory to make integration tests with ASP.NET Core 5, it should work like a charm
Like this:
Recommend
-
6
Cannot change Sitecore item Presentation Details – InvalidOperationException placeholder id
-
9
ASP.NET Core 5 & EntityFramework Core: Clean, clear and fluent integration tests with Calzolari.TestServer.EntityFramework, FluentAssertion.Web and xUnit 2021-04-17 by
-
9
asp dotnet core 基于 TestServer 做集成测试我有一个古老的 dotnet core 3.1 的 asp dotnet core 项目,现在我准备将他升级到 dotnet 5 了。但是我不想和博客园一样翻车,因此我需要做一点集成测试的辅助,尽管依然还是翻车了,但是我要学习博客园伟大的...
-
8
ASP.NET Core Integration Tests With TestServer - How Did I Not Know About This? Nov 18, 2021 I’ve been looking for ways to write better integration tests. My
-
6
Cere Network to Integrate With Boba Network To Provide Decentralized Data Solutions to It’s Users Berlin, Germany, 25th March, 2022, Today, Boba Network and Cere Network ann...
-
7
Closing Form with Gif Launches InvalidOperationException advertisements This is clearly a problem of me not understanding how to...
-
5
Wednesday, 06 July 2022 15:55 Ping Identity partners with Deloitte Australia to bring identity security solutions to Australia’s large enterprises By Ping Identity
-
1
Incorrect PIN? Your memory isn't bad, it's a bug Netflix currently has no solution for...
-
7
Mocking an HttpClient using ASP.NET Core TestServer 01/30/2023I' ve already written about
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK