asp建站软件,中铁建设门户网登录入口在哪,四川水利工程造价信息网,汽车充电桩网站建设中企动力技术支持学习进步老张的哲学不定期更新的日常在平时的开发中#xff0c;我们很少会关注到测试的问题#xff0c;更别说集成测试了#xff0c;除非是公司有硬性要求或者是自己的开源项目中#xff0c;为了整体架构的完整性#xff0c;需要用测试来做辅助点缀#xff0c;而更多的也… 学习·进步老张的哲学不定期更新的日常 在平时的开发中我们很少会关注到测试的问题更别说集成测试了除非是公司有硬性要求或者是自己的开源项目中为了整体架构的完整性需要用测试来做辅助点缀而更多的也仅仅是单元测试说的就是我自己????最近在写书的时候才进一步考虑到这一点如何在一个ASP.NET Core框架中引入集成测试呢 这里我结合这三年开源的经验总结了一些心得给大家分享一下如果有更好的建议欢迎在评论区进行留言哟。PS单元测试就不说了比较简单最多就是依赖注入和MOCK的问题不会的话也可以留言。方案一万物皆可Mock 在软件测试当中我们经常甚至是到处都会用到mock来处理对象实例化的问题在单元测试中mock十分常见毕竟是为了测试一个小模块其他的就不需要考虑直接mock就行了如果在集成测试的时候如何测试接口呢比如BlogController如何使用我在blog.core项目中就是这么使用到的示例代码如下 MockIBlogArticleServices mockBlogSev new MockIBlogArticleServices();MockILoggerBlogController mockLogger new MockILoggerBlogController();BlogController blogController;private IBlogArticleServices blogArticleServices;DI_Test dI_Test new DI_Test();public BlogController_Should(){mockBlogSev.Setup(r r.Query());var container dI_Test.DICollections();blogArticleServices container.ResolveIBlogArticleServices();blogController new BlogController(mockLogger.Object);} 说句实话这并非是集成测试这种写法可能比较低端通过mock配合new创建了控制器然后调用接口看起来不是很高大上而且集成测试本来就是要测试整体性不能把所有的参数都mock吧。同时官方好像也说过不要到处使用mock。而且这种方案也要考虑如何使用依赖注入的问题所以这种方案做集成测试我给⭐⭐方案二实例化TestServer对象 这种是比较常见的也是微软官方架构项目eShopOnContainers的推荐方案简单来说就是微软提供了一个TestSever的类为我们提供一个类似WebHost的宿主服务器只不过是测试服务器那如何测试Controller控制器呢示例代码如下 public TestServer CreateServer(){var path Assembly.GetAssembly(typeof(CatalogScenariosBase)).Location;var hostBuilder new WebHostBuilder().UseContentRoot(Path.GetDirectoryName(path)).ConfigureAppConfiguration(cb {cb.AddJsonFile(appsettings.json, optional: false).AddEnvironmentVariables();}).UseStartupStartup();var testServer new TestServer(hostBuilder);testServer.Host.MigrateDbContextCatalogContext((context, services) {var env services.GetServiceIWebHostEnvironment();var settings services.GetServiceIOptionsCatalogSettings();var logger services.GetServiceILoggerCatalogContextSeed();new CatalogContextSeed().SeedAsync(context, env, settings, logger).Wait();}).MigrateDbContextIntegrationEventLogContext((_, __) { });return testServer;} 可以看到通过new TestServer()的方式生成一个服务器就可以发起请求了核心的还是我们的WebHostBuilder。至于如何调用就更简单了直接对server发起HttpClient请求即可 using (var server CreateServer()){var response await server.CreateClient().GetAsync(Get.ItemById(1));response.EnsureSuccessStatusCode();} 这种是很简单的而且也不用考虑mock的问题毕竟用的直接就是web项目的WebHost宿主机Builder来构建的。 但是有一个很致命的问题我们在.NET5以后使用Autofac做依赖注入的容器而且ConfigureServices也是没有返回值的这样在使用上面的TestServer就会报错提示找不到Autofac服务。 但是如果你查看eShopOnContainers的源码后就知道他们还是将ConfigureServices做了返回值处理 public IServiceProvider ConfigureServices(IServiceCollection servic{// 自定义服务扩展services.AddAppInsight(Configuration)// and so on....AddCustomMVC(Configuration);// 使用Autofac依赖注入容器var container new ContainerBuilder();container.Populate(services);return new AutofacServiceProvider(container.Build());} 如果你能接受这种依赖注入的方式的话也是可以使用这种方案的这是一个注意点要知道。所以这种方案做集成测试我给⭐⭐⭐⭐方案三使用.UseTestServer() 除了上面的这种方式还有一种方式也是官方提供的比较类似也是通过创建宿主机服务器的形式不过是新的HostBuilder的ConfigureWebHostDefaults方式创建的示例代码如下public static IHostBuilder GetTestHost()
{return new HostBuilder()//替换autofac作为DI容器.UseServiceProviderFactory(new AutofacServiceProviderFactory()).ConfigureWebHostDefaults(webBuilder {webBuilder.UseTestServer().UseStartupStartup();}).ConfigureAppConfiguration((host, builder) {builder.SetBasePath(Directory.GetCurrentDirectory());builder.AddJsonFile(appsettings.json, optional: true);builder.AddEnvironmentVariables();});
} 既然上面说了我们不能单独处理自定义容器我们就和之前一样指定就好设计思路和我们的WebApi中的Program.cs特别像然后使用起来就更加简单了 using var server await ArticleScenariosBase.GetTestHost().StartAsync();// Action 发起接口请求var response await server.GetTestClientWithToken().GetAsync(/api/blogs?page1pageSize5);// Assert 确保接口状态码是200response.EnsureSuccessStatusCode(); 这种方案不仅兼容了第二种方案的优点而且对之前我们设计的Autofac依赖注入容器没有做任何的修改。所以这种方案做集成测试我给⭐⭐⭐⭐⭐编者按Blog.Core开源三周年【原料】 个人开源项目Blog.Core马上就已经开源三周年了经过许许多多的小伙伴功能努力的结果希望给ASP.NET Core在国内的推广提供一个落地级别的案例。【制法】 A、累计提交上千次Commit B、配合前、后、认证、鉴权一体化方案 C、不完全统计被60公司使用中【调味】1.希望更多的小伙伴参与并提交PR。2.希望更多的公司和组织使用提供宝贵生产意见。3.希望可以得到组织的孵化让项目更进一步有意者可以联系我。Tips: 九月新内容敬请期待。HAPPY EVEY DAY!