使用 Alba 對 AspnetCore項目進行測試

来源:https://www.cnblogs.com/vipwan/p/18340537
-Advertisement-
Play Games

前言 在AspnetCore生態系統中,我們測試項目一般使用Microsoft.AspNetCore.TestHost的TestServer 到.NET6後提供的Microsoft.AspNetCore.Mvc.Testing的WebApplicationFactory,後者是前者的封裝,專門用於測 ...


前言

在AspnetCore生態系統中,我們測試項目一般使用Microsoft.AspNetCore.TestHostTestServer 到.NET6後提供的Microsoft.AspNetCore.Mvc.TestingWebApplicationFactory,後者是前者的封裝,專門用於測試 ASP.NET Core 應用程式。它簡化了創建和配置測試伺服器的過程。而Alba也是基於前者的封裝,同樣提供了一些好用的測試體驗

使用 Alba 進行集成測試

以下我們來體驗一下TA的一些好用的測試體驗:

首先,你需要在項目中安裝 Alba 包。可以使用以下命令通過 NuGet 包管理器進行安裝:

dotnet add package Alba

為了演示 Alba 的使用,我們首先創建一個簡單的 ASP.NET Core 應用程式。這個應用程式包含一個返回 "Hello, World!" 的 MinimalApi請求。

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello, World!");
app.Run();

namespace TestCase
{
    public partial class Program { } //定義一個入口點用於測試
}

接下來,我們使用 Alba 創建一個基於xUnit的集成測試,測試上述應用程式。

using Alba;
public class IntegrationTests
{
    [Fact]
    public async Task Get_Home_Returns_HelloWorld()
    {
        using var host = await AlbaHost.For<TestCase.Program>(builder =>
        {
            // 這裡可以配置服務和中間件
        });
        await host.Scenario(scenario =>
        {
            scenario.Get.Url("/");
            scenario.StatusCodeShouldBeOk();
            scenario.ContentShouldBe("Hello, World!");
        });
    }
}

AlbaHost有一個方法Scenario(x=>{})用於定義測試場景,比如上面的測試用例,場景使用GET請求起始頁並斷言是否返回200,以及返回的文本是否是Hello, World!

對於內置場景沒有支撐到位的斷言,我們也可以使用參數接收IScenarioResult自行斷言:

var myScenario = await _host.Scenario(_ =>
{
    _.Get.Url("/");
});
Assert.Equal("true", myScenario.ReadAsText());
Assert.Equal(200, myScenario.Context.Response.StatusCode);

對於POST等方式提供鏈式的語法風格,Alba會自動幫我們序列化:

using Alba;
public class IntegrationTests
{
    [Fact]
    public async Task Post_Data_Returns_Correct_Response()
    {
        using var host = await AlbaHost.For<TestCase.Program>();
        await host.Scenario(scenario =>
        {
            scenario.Post.Json(new { Name = "Test" }).ToUrl("/data");
            scenario.StatusCodeShouldBeOk();
            scenario.ContentShouldBe("Received: Test");
        });
    }
}

對於XmlFormData的POST,Scenario也是提供支持的,例如:

//xml
scenario.Post.Xml(new Input {Name = "vipwan", Age = 18});
//form
public async Task write_form_data(IAlbaHost system)
{
    var form1 = new Dictionary<string, string>
    {
        ["a"] = "what?",
        ["b"] = "now?",
        ["c"] = "really?"
    };
    await system.Scenario(_ =>
    {
        // This writes the dictionary values to the HTTP
        // request as form data, and sets the content-length
        // header as well as setting the content-type
        // header to application/x-www-form-urlencoded
        _.WriteFormData(form1);
    });
}

當然除了傳參的時候自動序列化,Alba對響應的返回也提供了反序列化支持:

public async Task read_json(IAlbaHost host)
{
    var result = await host.Scenario(_ =>
    {
        _.Get.Url("/output");
    });
    var output = result.ReadAsJsonAsync<Output>();
}
//或者
public async Task read_json_shorthand(IAlbaHost host)
{
    var output = await host.GetAsJson<Output>("/output");
}

如果需要測試需要鑒權認證的請求,Alba也幫我們做了封裝.我們只需要實例化AuthenticationStub或者JwtSecurityStub亦或者實現OpenConnectExtension,然後在實例化AlbaHost時傳入即可!

var securityStub = new AuthenticationStub()
    .With("foo", "bar")//演示添加的claim
    .With(JwtRegisteredClaimNames.Email, "[email protected]")//演示添加的claim
    .WithName("vipwan");
myHost = await AlbaHost.For<WebAppSecuredWithJwt.Program>(securityStub);

如上面的代碼只要我們使用myHost實例創建的任何場景將自動附加相應的認證信息:

//當請求需要認證的時候也可以通過測試
app.MapGet("/", () => "Hello, World!").RequireAuthorization();

對於請求Alba還支持請求的AOP,比如請求前後我們需要對HttpContext做一些改動:

public void sample_usage(AlbaHost system)
{
    // Synchronously
    system.BeforeEach(context =>
    {
        // Modify the HttpContext immediately before each
        // Scenario()/HTTP request is executed
        context.Request.Headers.Add("trace", "something");
    });
    system.AfterEach(context =>
    {
        // perform an action immediately after the scenario/HTTP request
        // is executed
    });
    // Asynchronously
    system.BeforeEachAsync(context =>
    {
        // do something asynchronous here
        return Task.CompletedTask;
    });
    system.AfterEachAsync(context =>
    {
        // do something asynchronous here
        return Task.CompletedTask;
    });
}

這裡介紹了一些Alba的特性和使用方式,當然還不完善,如果你對這個庫感興趣可以點擊鏈接查看官方的文檔

總結

Alba 是一個比較簡單的測試庫,提供了我們對Web項目測試常用的場景封裝,下圖是AlbaHost簡單架構:
image

Alba 提供了多種便捷的測試方式,使得編寫和執行集成測試變得更加簡單和高效。無論是基本的 HTTP 請求測試、帶有依賴註入的請求測試、POST 請求測試、帶有認證的請求測試,還是複雜的請求和響應測試,Alba 都能很好地滿足你的需求。通過使用 Alba,你可以更輕鬆地編寫可靠的集成測試,確保你的應用程式在各種情況下都能正常工作。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 作者:小塵 鏈接:https://juejin.cn/post/7357172505961578511 前言 見過幾千行代碼的 controller嗎?我見過。 見過全是 try catch 的 controller 嗎,我見過。 見過全是欄位校驗的 controller 嗎,我見過。 見過全是業務 ...
  • memset() 描述 C 庫函數 void *memset(void *str, int c, size_t n) 用於將一段記憶體區域設置為指定的值。 memset() 函數將指定的值 c 複製到 str 所指向的記憶體區域的前 n 個位元組中,這可以用於將記憶體塊清零或設置為特定值。 在一些情況下,需 ...
  • C 庫函數 - strcmp() 描述 C 庫函數 int strcmp(const char *str1, const char *str2) 把 str1 所指向的字元串和 str2 所指向的字元串進行比較。 聲明 下麵是 strcmp() 函數的聲明。 int strcmp(const cha ...
  • 前言 今天推薦一款用 .NET 和 Vue3 實現的開源許可權管理系統。它的界面清爽乾凈,功能強大,還具備靈活的角色許可權分配功能,能夠滿足不同規模企業的管理需求。無論你是開發新手還是大神,都能輕鬆上手,快速搭建起自己的許可權管理體系。別再猶豫了,趕快來試試吧! 項目簡介 Malus是海棠的意思,顧名思義 ...
  • 委托與事件是C#中歷史比較悠久的技術,從C#1.0開始就有了,核心作用就是將方法作為參數(變數)來傳遞和使用。其中委托是基礎,需要熟練掌握,編程中常用的Lambda表達式、Action、Func都是委托,包括事件也是基於委托實現的。 ...
  • 自動生成欄位值,咱們首先想到的是主鍵列(帶 IDENTITY 的主鍵)。EF Core 預設的主鍵配置也是啟用 Identity 自增長的,而且可以自動標識主鍵。前提是代表主鍵的實體屬性名要符合以下規則: 1、名字叫 ID、id、或 Id,就是不分大小寫; 2、名字由實體類名 + Id 構成。比如, ...
  • 前言 這算是一篇學習記錄博客了,主要是學習語義內核(Semantic Kernel)的實踐,以及Aspire進行全棧開發的上手體驗,我是採用Aspire同時啟動API服務,Blazor前端服務以及WinUI的桌面端項目,同時進行三個項目的代碼修改,整體感覺很方便,如果代碼都修改了只需要啟動Aspir ...
  • 或許你接觸過Jenkins, 在我理解就是拉取源碼,然後構建成鏡像,最後啟動容器! 但是這個功能對於小記憶體的伺服器來說就是奢望了! 今天介紹一個新版本,把你這個遺憾彌補下! 在PasteSpider中,也是支持拉取源碼,然後編譯發佈的!!! 以下案例使用svn作為源碼管理 如果你使用git作為源碼管 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...