.net网站开发实站,网站建设增长率,手机微网站怎么制作,wordpress访问次数插件简介 Microsoft.AspNetCore.TestHost是可以用于Asp.net Core 的功能测试工具。很多时候我们一个接口写好了#xff0c;单元测试什么的也都ok了#xff0c;需要完整调试一下#xff0c;检查下单元测试未覆盖到的代码是否有bug。步骤为如下#xff1a;程序打个断点-F5运行… 简介 Microsoft.AspNetCore.TestHost是可以用于Asp.net Core 的功能测试工具。很多时候我们一个接口写好了单元测试什么的也都ok了需要完整调试一下检查下单元测试未覆盖到的代码是否有bug。步骤为如下程序打个断点-F5运行-通常需要登录个测试账号-查找要调试api的入口-获得断点开始调试代码报错很多时候需要停止调试修改-回到第一步。如此反复循环做着重复的工作Microsoft.AspNetCore.TestHost正是为了解决这个问题它可以让你使用xTest或者MSTest进行覆盖整个HTTP请求生命周期的功能测试。 进行一个简单的功能测试 新建一个Asp.net Core WebApi和xUnit项目 ValuesController里面自带一个Action 我们在xUnit项目里面模拟访问这个接口首选安装如下nuget包 Microsoft.AspNetCore.TestHost Microsoft.AspNetCore.All很多依赖懒得找的话直接安装这个集成包百分之90涉及到AspNetCore的依赖都包含在里面 然后需要引用被测试的AspnetCoreFunctionalTestDemo项目新建一个测试类ValuesControllerTest 将GetValuesTest方法替换为如下代码其中startup类是应用自AspnetCoreFunctionalTestDemo项目 [Fact] public void GetValuesTest(){ var client new TestServer(WebHost.CreateDefaultBuilder().UseStartupStartup()).CreateClient(); string result client.GetStringAsync(api/values).Result;Assert.Equal(result, JsonConvert.SerializeObject(new string[] { value1, value2 }));} 此时在ValueController打下断点 运行GetValuesTest调试测试 成功进入断点我们不用启动浏览器就可以进行完整的接口功能测试了。 修改内容目录与自动授权 上面演示了如何进行一个简单的功能测试但是存在两个缺陷 webApi在测试的时候实际的运行目录是在FunctionalTest目录下 对需要授权的接口不能正常测试会得到未授权的返回结果 1.内容目录 我们可以在Controller的Get方法输出当前的内容目录 内容目录是在测试x项目下这与我们的预期不符如果webapi项目对根目录下的文件有依赖关系例如appsetting.json则会找不到该文件解决的办法是在webHost中手动指定运行根目录 [Fact]public void GetValuesTest()
{ var client new TestServer(WebHost.CreateDefaultBuilder() .UseContentRoot(GetProjectPath(AspnetCoreFunctionalTestDemo.sln, , typeof(Startup).Assembly)).UseStartupStartup()).CreateClient(); string result client.GetStringAsync(api/values).Result;Assert.Equal(result, JsonConvert.SerializeObject(new string[] { value1, value2 }));
}/// summary/// 获取工程路径/// /summary/// param nameslnName解决方案文件名例test.sln/param/// param namesolutionRelativePath如果项目与解决方案文件不在一个目录例如src文件夹中则传src/param/// param namestartupAssembly程序集/param/// returns/returnsprivate static string GetProjectPath(string slnName, string solutionRelativePath, Assembly startupAssembly)
{ string projectName startupAssembly.GetName().Name; string applicationBasePath PlatformServices.Default.Application.ApplicationBasePath; var directoryInfo new DirectoryInfo(applicationBasePath); do{ var solutionFileInfo new FileInfo(Path.Combine(directoryInfo.FullName, slnName)); if (solutionFileInfo.Exists){ return Path.GetFullPath(Path.Combine(directoryInfo.FullName, solutionRelativePath, projectName));}directoryInfo directoryInfo.Parent;} while (directoryInfo.Parent ! null); throw new Exception($Solution root could not be located using application root {applicationBasePath}.);} GetProjectPath方法采用递归的方式找到startup的项目所在路径此时我们再运行 2.自动授权 每次测试时手动登录这是一件很烦人的事情所以我们希望可以自动话这里演示的时cookie方式的自动授权 首先在startup文件配置cookie认证 namespace AspnetCoreFunctionalTestDemo
{ public class Startup{ public Startup(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.AddMvc(); services.AddAuthentication(o o.DefaultScheme CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(o {o.ExpireTimeSpan new TimeSpan(0, 0, 30);o.Events.OnRedirectToLogin (context) {context.Response.StatusCode 401; return Task.CompletedTask;};}); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IHostingEnvironment env){ if (env.IsDevelopment()){app.UseDeveloperExceptionPage();} app.UseAuthentication();app.UseMvc();}}
} 这里覆盖了cookie认证失败的默认操作改为返回401状态码。 在valuesController新增登录的Action并配置Get的Action需要授权访问 namespace AspnetCoreFunctionalTestDemo.Controllers
{[Route(api/[controller])] public class ValuesController : Controller{ // GET api/values [HttpGet,Authorize] public IEnumerablestring Get([FromServices]IHostingEnvironment env){ return new string[] { value1, value2 };} // POST api/values[HttpGet(Login)] public void Login(){ var identity new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);identity.AddClaim(new Claim(ClaimTypes.Name, huanent)); var principal new ClaimsPrincipal(identity);HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal).Wait();}}
} 此时我们使用测试项目测试Get方法 如我们预期返回了401说明未授权。我们修改下GetValuesTest namespace FunctionalTest
{ public class ValuesControllerTest{[Fact] public void GetValuesTest(){ var client new TestServer(WebHost.CreateDefaultBuilder().UseStartupStartup().UseContentRoot(GetProjectPath(AspnetCoreFunctionalTestDemo.sln, , typeof(Startup).Assembly))).CreateClient(); var respone client.GetAsync(api/values/login).Result;SetCookie(client, respone); var result client.GetAsync(api/values).Result;} private static void SetCookie(HttpClient client, HttpResponseMessage respone){ string cookieString respone.Headers.GetValues(Set-Cookie).First(); string cookieBody cookieString.Split(;).First();client.DefaultRequestHeaders.Add(Cookie, cookieBody);} /// summary/// 获取工程路径 /// /summary/// param nameslnName解决方案文件名例test.sln/param/// param namesolutionRelativePath如果项目与解决方案文件不在一个目录例如src文件夹中则传src/param/// param namestartupAssembly程序集/param/// returns/returnsprivate static string GetProjectPath(string slnName, string solutionRelativePath, Assembly startupAssembly){ string projectName startupAssembly.GetName().Name; string applicationBasePath PlatformServices.Default.Application.ApplicationBasePath; var directoryInfo new DirectoryInfo(applicationBasePath); do{ var solutionFileInfo new FileInfo(Path.Combine(directoryInfo.FullName, slnName)); if (solutionFileInfo.Exists){ return Path.GetFullPath(Path.Combine(directoryInfo.FullName, solutionRelativePath, projectName));}directoryInfo directoryInfo.Parent;} while (directoryInfo.Parent ! null); throw new Exception($Solution root could not be located using application root {applicationBasePath}.);}}
} 我们首先访问api/Values/Login获取到Cookie然后讲cookie附在httpclient的默认http头上这样就能够成功访问需要授权的接口了 总结 通过上面演示我们已经可以很大程度地模拟了整个api请求让我们可以方便地一键调试目标接口再也不用开浏览器或postman了。 附上演示项目地址https://github.com/huanent/AspnetCoreFunctionalTestDemo 原文http://www.cnblogs.com/huanent/p/7886282.html .NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com