Asp .Net Core 3.0测试中自定义Startup类致视图无法加载问题
我帮你分析下这个问题,在Asp.Net Core 3.0中,视图的加载机制相比2.2有一些变化,尤其是当使用自定义TestStartup继承主项目Startup时,容易出现视图路径识别的问题。下面是具体的解决思路和方案:
问题根源
当你使用自定义TestStartup时,虽然继承了主项目的Startup,但在测试项目中配置UseSolutionRelativeContentRoot后,视图引擎并没有正确识别到测试项目下复制的Views文件夹。另外,Asp.Net Core 3.0默认会将视图编译为独立的程序集,如果你没有把主项目的视图程序集引入测试项目,或者没有正确配置视图查找路径,就会出现找不到视图的错误。
解决方案
方案1:在TestStartup中明确配置视图查找路径
修改你的TestStartup类,在ConfigureServices方法中添加视图路径的配置,确保视图引擎能找到测试项目下的Views文件夹:
public class TestStartup : Startup { private readonly IWebHostEnvironment _env; public TestStartup(IConfiguration configuration, IWebHostEnvironment env) : base(configuration) { _env = env; } public override void ConfigureServices(IServiceCollection services) { base.ConfigureServices(services); // 配置视图查找路径,指向测试项目的Views文件夹 services.Configure<RazorViewEngineOptions>(options => { options.ViewLocationFormats.Add($"/{_env.ContentRootPath}/Views/{{1}}/{{0}}.cshtml"); options.ViewLocationFormats.Add($"/{_env.ContentRootPath}/Views/Shared/{{0}}.cshtml"); }); } }
方案2:确保测试项目引用主项目的视图程序集
如果主项目的视图被编译为独立的程序集(通常命名为YourMainProjectName.Views.dll),在测试项目中添加对这个程序集的引用,并在TestStartup中将其添加到应用部分:
public override void ConfigureServices(IServiceCollection services) { base.ConfigureServices(services); var viewsAssembly = typeof(YourMainProjectName.Views.Home.Index).Assembly; services.AddControllersWithViews() .AddApplicationPart(typeof(Startup).Assembly) .AddApplicationPart(viewsAssembly); }
这样测试时会直接使用主项目编译好的视图,不需要复制Views文件夹到测试项目。
方案3:在TestServerFactory中正确设置内容根
修改你的TestServerFactory,在CreateWebHostBuilder中直接设置内容根为测试项目的路径,而不是在WithWebHostBuilder中设置:
public class TestServerFactory : WebApplicationFactory<TestStartup> { protected override IWebHostBuilder CreateWebHostBuilder() { var testProjectDir = Path.GetFullPath("ViewsTestingTests"); return WebHost.CreateDefaultBuilder(null) .UseContentRoot(testProjectDir) .UseStartup<TestStartup>(); } }
同时确保测试项目下的Views文件夹的所有.cshtml文件的“复制到输出目录”属性设置为“如果较新则复制”或“始终复制”。
方案4:简化TestStartup的使用(推荐)
如果你的TestStartup暂时只是继承主Startup还没有重写方法,可以直接在TestServerFactory中使用主Startup,然后通过WithWebHostBuilder添加后续需要重写的配置,这样既保留了主项目的视图配置,又能满足自定义需求:
public class TestServerFactory : WebApplicationFactory<Startup> { protected override IWebHostBuilder CreateWebHostBuilder() { return WebHost.CreateDefaultBuilder(null) .UseStartup<Startup>(); } }
然后在测试方法中:
var client = factory.WithWebHostBuilder(builder => { builder.UseSolutionRelativeContentRoot(testProjectDir); // 在这里添加你需要重写的配置,比如替换服务等 }).CreateClient();
验证步骤
- 确认测试项目下的
Views文件夹结构和主项目一致,.cshtml文件的复制属性正确。 - 运行测试前清理并重新生成解决方案,确保视图程序集或复制的视图文件正确输出到测试项目的bin目录。
内容的提问来源于stack exchange,提问作者Piotr Kościelniak

