asp dotnet core 不正經的提升效率的單元測試方法

在寫 asp dotnet core 時,如果沒有單元測試保證,需要每個方法都從 web api 的入口開始運行,此時的執行效率是很低的。而如果寫單元測試,又有一個坑的問題是寫單元測試也是需要時間的。本文告訴大家一些提高效率的方法,這些方法不是正經的用法,但是能提升效率。至於能不能用好不好用就請觀衆老爺自己決定

CUnit 中文命名單元測試

在寫單元測試時,小夥伴說需要讓單元測試的方法名符合 條件_執行_結果 而要求這個方法命名爲英文,我的英文就超級渣,這一點 少珺 小夥伴可以幫我證明。於是你會看到我寫了以下的測試 WhenABuDengYuThree_DokanarkelawNinirahajairi_SetSlj 的命名,而如果要我優化這個單元測試的命名,大家都知道,有些小夥伴和我一樣想一個好的命名可能佔了開發的一半時間

寫單元測試時,大量的單元測試方法命名將會佔用大量的時間,讓小夥伴不願意寫單元測試。或者寫出來的單元測試的只有自己能讀懂

在一個團隊裏面的,如果英文水平參差不齊,如我所在的團隊有英文特別厲害的walterlv天龍也有英文特別差國語也特別差的大壯哥,還有英文有毒的本渣。此時用英文命名的單元測試就是一個神坑,除非團隊能成立一個改名部專門協助命名

一個解決方法是乾脆用中文命名單元測試算了,請看下面單元測試

[TestClass]
public class DemoTest
{
    [ContractTestCase]
    public void Foo()
    {
        "當滿足 A 條件時,應該發生 A' 事。".Test(() =>
        {
            // Arrange
            // Action
            // Assert
        });
        
        "當滿足 B 條件時,應該發生 B' 事。".Test(() =>
        {
            // Arrange
            // Action
            // Assert
        });
    }
}

運行單元測試將看到這樣的結果視圖

只要有任何一個單元測試炸了,相信小夥伴看提示特別快就知道哪裏炸了

使用這個庫的前提是用 NuGet 安裝 MSTestEnhancer 庫,如果是 SDK 格式的項目文件,可以添加下面代碼

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
    <PackageReference Include="Moq" Version="4.13.1" />
    <PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
    <PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
    <PackageReference Include="coverlet.collector" Version="1.0.1" />
    <PackageReference Include="MSTestEnhancer" Version="1.6.0" />
  </ItemGroup>

注意版本號需要你自己更新

在單元測試的方法裏面,推薦寫某個需要測試的方法,在方法上面添加特性 ContractTestCase 請看代碼

    [ContractTestCase]
    public void Foo()

接下來在方法裏面用一段字符串和 .Test 寫出對應的單元測試

        "當滿足 A 條件時,應該發生 A' 事。".Test(() =>
        {
            // Arrange
            // Action
            // Assert
        });

一個例子是我在DotNetGitLabWebHook用到的方法,代碼請看 github 是不是覺得寫起來特別快

用 CUnit(MSTestEnhancer) 能讓團隊內小夥伴寫單元測試的效率提升,也能提升團隊裏面讀單元測試以及單元測試炸瞭解決的效率

現在問題只有一個,你的團隊內對中文的看法是如何?千萬不要在我的博客下評論,我的博客的評論做的很渣,如果有很多人都在評論我的博客就用不了

利用原有依賴注入

在 asp dotnet core 的各個類可以在構造函數添加依賴注入的方法,如我的DotNetGitLabWebHook就在各個類裏面的構造函數添加了依賴注入

在 asp dotnet core 默認的構造函數依賴注入非常好用,例如我的 GitLabMRCheckerFlow.cs 用到兩個類 Notify 和 FileChecker 類,而 Notify 用到了 IConfiguration 配置,於是我可以這樣寫

    public class Notify
    {
        /// <inheritdoc />
        public Notify(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // 忽略代碼
    }

    // GitLabMRCheckerFlow.cs

            public GitLabMRCheckerFlow(Notify notify, FileChecker fileChecker)

在 Startup.cs 的 ConfigureServices 添加註入

            services.AddScoped<GitLabMRCheckerFlow>();
            services.AddScoped<Notify>();
            services.AddScoped<FileChecker>();

代碼請看 Startup.cs

此時獲取對象的方法都是放在構造函數參數,此時各個參數對應的類的創建也會自動注入構造參數。如在 GitLabMRCheckerFlow 需要傳入 Notify 參數,而創建 Notify 類需要傳入 IConfiguration 參數,這些都會在自帶的依賴注入完成

在寫 Controller 的單元測試時,難道我是需要運行一個 ASP.NET Core 服務,然後用 postman 進行測試?這樣的效率太低了,可以嘗試直接創建類調用對應的方法。而如果需要每個類都自己創建,這個創建效率實在太低,因爲創建一個類需要在他的構造函數傳入其他類,而這個類的構造函數可能後續修改,這樣的單元測試小夥伴都想砍人

簡單的方法是在單元測試創建服務

            var hostBuilder = Program.CreateHostBuilder(new string[0]);
            var build = hostBuilder.Build();
            var serviceProvider = build.Services;

上面的代碼在單元測試裏面調用,調用上面代碼將會創建服務

然後拿到 serviceProvider 創建對象。如我需要測試 GitLabWebHookController 我可以給他的構造函數每個參數都在 serviceProvider 獲取,此時就不需要手動創建

        public void MergeRequestTest()
        {
            var hostBuilder = Program.CreateHostBuilder(new string[0]);
            var build = hostBuilder.Build();
            var serviceProvider = build.Services;
            
            using (var scope = serviceProvider.CreateScope())
            {
                var gitLabMrCheckerFlow = scope.ServiceProvider.GetService<GitLabMRCheckerFlow>();

                var gitLabWebHookController = new GitLabWebHookController(gitLabMrCheckerFlow);
                gitLabWebHookController.MergeRequest(TestMRJson.GetObject());
            }
        }

這裏有細節是 Controller 的注入有很多參數都是在 Scope 需要創建

而如果我的 Controller 有某些參數需要使用 Fake 或 Mock 的,這些參數就自己用 Mock 啦

通過這個方法會降低單元測試運行速度,但是能提升寫單元測試的效率

我搭建了自己的博客 https://blog.lindexi.com/ 歡迎大家訪問,裏面有很多新的博客。只有在我看到博客寫成熟之後纔會放在csdn或博客園,但是一旦發佈了就不再更新

如果在博客看到有任何不懂的,歡迎交流,我搭建了 dotnet 職業技術學院 歡迎大家加入

如有不方便在博客評論的問題,可以加我 QQ 2844808902 交流

知識共享許可協議
本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名林德熙(包含鏈接:http://blog.csdn.net/lindexi_gd ),不得用於商業目的,基於本文修改後的作品務必以相同的許可發佈。如有任何疑問,請與我聯繫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章