日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用Microsoft.AspNetCore.TestHost进行完整的功能测试

發布時間:2023/12/4 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用Microsoft.AspNetCore.TestHost进行完整的功能测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡介

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().UseStartup<Startup>()).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)).UseStartup<Startup>()).CreateClient(); ? ?string result = client.GetStringAsync("api/values").Result;Assert.Equal(result, JsonConvert.SerializeObject(new string[] { "value1", "value2" })); }/// <summary>/// 獲取工程路徑/// </summary>/// <param name="slnName">解決方案文件名,例test.sln</param>/// <param name="solutionRelativePath">如果項目與解決方案文件不在一個目錄,例如src文件夾中,則傳src</param>/// <param name="startupAssembly">程序集</param>/// <returns></returns>

    private 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 IEnumerable<string> 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().UseStartup<Startup>().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 name="slnName">解決方案文件名,例test.sln</param>/// <param name="solutionRelativePath">如果項目與解決方案文件不在一個目錄,例如src文件夾中,則傳src</param>/// <param name="startupAssembly">程序集</param>/// <returns></returns>private 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

    總結

    以上是生活随笔為你收集整理的使用Microsoft.AspNetCore.TestHost进行完整的功能测试的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。