如何在ASP.NET Core集成测试中从外部程序集注入依赖?
解决方案:在ASP.NET Core集成测试中注入测试项目类且避免404问题
针对你的场景,有两种合理方案可以避免将测试辅助类移入应用项目,同时解决控制器映射404的问题:
方案1:复用原项目Startup,动态替换依赖
不需要自定义测试专属的Startup类,直接复用应用原有的Startup,在构建TestHost时通过ConfigureServices扩展方法覆盖或注入测试项目中的依赖:
var webHostBuilder = new WebHostBuilder() .UseStartup<YourAppNamespace.Startup>() // 引用原项目的Startup .ConfigureServices(services => { // 移除原有的服务实现(如果需要) var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(ISomeService)); if (descriptor != null) { services.Remove(descriptor); } // 注入测试项目中定义的实现类 services.AddScoped<ISomeService, TestSpecificService>(); });
这种方式的优势是完全复用原应用的配置逻辑,只针对需要测试替换的依赖做调整,不会出现控制器扫描的问题。
方案2:在测试项目的Startup中显式指定控制器程序集
如果必须使用测试项目中的StartupLocalIntegrationTest,问题出在默认情况下ASP.NET Core只会扫描当前Startup所在程序集中的控制器,而你的控制器在应用项目程序集里,导致路由无法匹配返回404。只需在测试Startup的ConfigureServices中显式添加控制器所在程序集即可:
// 测试项目中的StartupLocalIntegrationTest类 public class StartupLocalIntegrationTest { public void ConfigureServices(IServiceCollection services) { // 注入测试项目中的依赖 services.AddScoped<ISomeService, TestSpecificService>(); // 显式添加应用项目的控制器程序集 services.AddControllers() .AddApplicationPart(typeof(YourAppController).Assembly); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 复用或调整原应用的中间件配置,比如: if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
关键说明
AddApplicationPart方法会告诉ASP.NET Core去指定的程序集中扫描控制器、视图组件等,解决测试项目Startup无法找到应用控制器的问题。- 确保测试项目已引用应用项目,且能访问到控制器类型(如果控制器是内部类,可在应用项目的
AssemblyInfo.cs中添加[assembly: InternalsVisibleTo("YourTestProjectName")])。
额外建议
优先选择方案1,因为它能最大程度保留原应用的配置一致性,减少测试环境与生产环境的差异;只有当需要大幅修改测试环境的启动逻辑时,再考虑方案2。
内容的提问来源于stack exchange,提问作者Claus Appel
相关产品推荐
相关产品推荐

