1. 程式人生 > >ASP.NET Core Web API 整合測試

ASP.NET Core Web API 整合測試

本文需要您瞭解ASP.NET Core Web API 和 xUnit的相關知識.

整合測試 vs 單元測試

測試金字塔, 但它只是一個指導性的概念.

如果所單元測試是對一個元件進行隔離測試的話, 那麼整合測試則是測試多個元件共同協作產生出期待的結果.

單元測試通常很快. 而整合測試則慢的多, 因為它需要很多配置, 並且可能依賴於外部的元件, 例如資料庫, 網路, 檔案等.

通常在一個專案裡單元測試要比整合測試多很多.

單元測試通常依賴於mock的元件, 而整合測試則使用可執行的元件.

注意: 如果一個行為可以通過單元測試或整合測試來測試的話, 那麼應該使用單元測試

.

如何進行整合測試

如果我想測試一個API Controller的Action, 我可能需要把這個專案執行起來, 等它跑起來, 傳送請求並檢驗結果. 但這樣做的話需要很多的配置工作, 並且很麻煩.

幸好ASP.NET Core 提供了一個Microsoft.AspNetCore.TestHost 庫, 使用它就無需單獨去執行被測試系統了.

ASP.NET Core應用裡, 我們在Program.cs裡建立WebHostBuilder, 並配置Kestrel Web伺服器, 使用Startup類進行應用配置, 註冊服務和中介軟體等. 最終在WebHostBuilder上使用Build()來建立WebHost的例項, 它可以用來在特定的URL和埠上執行並監聽請求.


而這個TestHost庫也使用了WebHostBuilder, 但它會自己把構建和執行web宿主的工作處理好, 也就是創建出了一個TestServer. TestServer不會在網路上進行監聽, TestServer建立了一個名為Host的屬性, 它的型別是IWebHost, 它可以用來處理記憶體裡的請求物件. TestServer還會暴露一個HttpClient, 你可以用它來發送請求到被測試系統. 整個互動的過程都是在記憶體裡完成的.

下圖是被測試系統在生產環境和整合測試使用TestServer情形下的對比圖:

圖中:

當應用/被測試系統在生產環境執行的時候, 它使用Kestrel伺服器, 監聽HTTP請求, 並把它轉化為HttpContext, 然後再傳進ASP.NET Core的管道里.

TestServer不監聽網路請求, 它使用HttpClient在記憶體裡傳送請求.

仔細看一下整合測試時使用TestServer的流圖:

圖中可以看到: 測試程式碼建立TestServer, TestServer建立HttpClient. 測試程式碼使用HttpClient傳送請求接收響應. TestServer會轉化請求並交給ASP.NET Core MVC/API 應用來處理.

一個例子

首先需要為你的應用建立整合測試專案:

然後需要為專案新增Microsoft.AspNetCore.TestHost 這個庫:

被測試的是這個Controller的GetRoot()所對應的行為, 而不只是這個方法:

測試返回NoContent:

這裡面按照之前講的順序, 建立IWebHostBuilder, 並用它建立TestServer, 然後TestServer建立HttpClient. 隨後就使用httpClient傳送請求, 返回結果, Assert即可.

需要注意的是, 在建立IWebHostBuilder的時候, 我使用了被測試系統的Startup類來進行配置, 並設定的環境是Development.

由於我這個專案可以看作是真實專案, 所以第一次執行該測試的時候, 測試是Fail的. 因為Startup裡面有很多配置並不滿足測試要求.

在我把IpRateLimiting, HttpsRedirection, Authentication, AuthorizeFilter等中介軟體/元件去掉之後, 測試才通過:

所以這就引出了一個問題, Startup裡面的配置在開發時測試時 以及 生產執行時 可能是不太一樣的.

我的Startup裡面已經有很多程式碼了, 如果再進行環境判斷, 那就會更亂了.

所以我決定為整合測試新建立一個Startup配置類:

然後修改程式碼, 使用這個測試專用的Startup即可:

測試會通過.

被測試系統有依賴項

下面繼續測試GetRoot方法的另一個路徑, 這個路徑會用到RootController的依賴項IUrlHelper. 

在整合測試裡, 通常情況下是不使用Mocking技術的. 所以在這裡我也不會mock IUrlHelper:

這裡沒有mock任何東西. 此外這個被測試的行為需要設定AcceptHeader.

測試會Pass的, TestServer幫我搞定了一切:

優化測試配置

寫了兩個測試方法, 又引出了一個新的問題: 這兩個方法有一些共同的設定程式碼, 這些設定可能會比較耗資源. 我們可以把這些設定放在建構函式裡面, 但是如果使用Theory並含有多個InlineData的話, 就會多次執行建構函式裡的設定程式碼, 可能會非常好資源(時間).

而且我們可以使用WebApplicationFactory來構建TestServer, 使用WebApplicationFactory的好處是可以靈活的進行自定義配置. 

要使用WebApplicationFactory, 需要新增庫: Microsoft.AspNetCore.Mvc.Testing

 

使用該庫之後, 程式碼應該如下:

但是卻有一個問題, 這裡我選擇的時StartupIntegrationTest. 而電腦環境變數設定的是Development, 而除錯測試之後發現走的是StartupDevelopment.

也許這是個Bug? 或者就是這樣的意圖. 那我暫時還是使用原始的方法建立TestServer吧, 下面是我使用的程式碼:

建立一個TestServerFixture, 需要使用IDisposable來做清理工作:

而測試類注入該Fixture即可:

然後重跑測試, 會pass的:

一個複雜點的例子

我要測試這個Controller下CreateProduct方法對應的行為. 該Controller需要很多依賴項, 其中兩個還需要使用資料庫.

通常情況下整合測試裡使用的資料庫和生產環境中使用的資料庫不同, 在測試環境我更傾向於使用記憶體類資料庫.

EF Core裡面至少有兩個記憶體類的資料庫提供商:

  • Microsoft.EntityFrameworkCore.InMemory, 這個都應該知道.
  • Microsoft.EntityFrameworkCore.Sqlite. 雖然說Sqlite通常是把資料儲存到檔案, 但是提供商為它提供了一個記憶體模式, 把資料庫儲存到了記憶體裡.

在StartupIntegrationTest裡, 我就使用InMemory吧;

 下面是測試方法的程式碼:

這程式碼其實很簡單, 就是對應著被測試的Controller方法做一些需要的設定即可, 例如Headers, Content-Type等等.

需要注意的是Content-Type是在Content的Header裡設定, 而不是Request的Headers裡設定, 否則會報亂用Header的錯.

該測試會pass:

最後針對該行為再做一個Model驗證失敗的測試:

沒什麼不同, 就是model的Name屬性超長了.

這個測試同樣會通過:

整合測試就簡單介紹這些.......

相關推薦

ASP.NET Core Web API 整合測試中使用 Bearer Token

在 ASP.NET Core Web API 整合測試一文中, 我介紹了ASP.NET Core Web API的整合測試.  在那裡我使用了測試專用的Startup類, 裡面的配置和開發時有一些區別, 例如裡面去掉了使用者身份驗證相關的中介軟體. 但是有些被測試的行為裡面需要用到身份/授權資訊. 所以

ASP.NET Core Web API 整合測試

本文需要您瞭解ASP.NET Core Web API 和 xUnit的相關知識. 整合測試 vs 單元測試 測試金字塔, 但它只是一個指導性的概念. 如果所單元測試是對一個元件進行隔離測試的話, 那麼整合測試則是測試多個元件共同協作產生出期待的結果. 單元測試通常很快. 而整合測試則

使用 Swagger 自動生成 ASP.NET Core Web API 的文檔、在線幫助測試文檔(ASP.NET Core Web API 自動生成文檔)

地址 .cn 名稱 cor 生成文檔 def pos 構建 回車 對於開發人員來說,構建一個消費應用程序時去了解各種各樣的 API 是一個巨大的挑戰。在你的 Web API 項目中使用 Swagger 的 .NET Core 封裝 Swashbuckle 可以幫助你創建良好

如何在ASP.NET Core Web API測試中使用Postman

e30 googl 選項卡 for 並運行 讓我 結合 pos lis 使用Postman進行手動測試 如果您是開發人員,測試人員或管理人員,則在構建和使用應用程序時,有時了解各種API方法可能是一個挑戰。 使用帶有.NET Core的Postman為您的Web API生

Asp.Net Core Web Api圖片上傳(一)整合MongoDB儲存例項教程

Asp.Net Core Web Api圖片上傳及MongoDB儲存例項教程(一) 圖片或者檔案上傳相信大家在開發中應該都會用到吧,有的時候還要對圖片生成縮圖。那麼如何在Asp.Net Core Web Api實現圖片上傳儲存以及生成縮圖呢?今天我就使用MongoDB作為圖片儲存,然後使用SixLabors

ASP.NET Core Web API 最小化項目

asp新建項目打開VS2017 新建一個ASP.NET Core 應用程序 (.NET Core)項目,命名為miniwebapi。確定後選擇Web API 模板,並將“身份驗證”設置為“不進行身份驗證”。然後確定就創建好了項目,默認項目的csproj 文件內容如下:<Project Sdk="Micr

品嘗阿裏雲容器服務:初步嘗試ASP.NET Core Web API站點的Docker自動化部署

asp.net title build 阿裏雲服務器 arm web 容器服務 倉庫 acs 部署場景是這樣的,我們基於 ASP.NET Core 2.0 Preview 1 開發了一個用於管理緩存的 Web API ,想通過阿裏雲容器服務基於 Docker 部署為內網服務

ASP.NET CORE WEB API DEMO 01

dsi del turn adr arch pda host result arc using System; using System.Collections.Concurrent; using System.Collections.Generic; namespac

ASP.NET Core Web API實現圖片下載

前端訪問下載圖片API下載圖片。 一、ASP.NET Core Web API程式碼 方案一: [Route("api/[controller]")] [ApiController

ASP.NET Core 實戰:使用 ASP.NET Core Web API 和 Vue.js,搭建前後端分離框架

前言         這幾年前端的發展速度就像坐上了火箭,各種的框架一個接一個的出現,需要學習的東西越來越多,分工也越來越細,作為一個 .NET Web 程式猿,多瞭解瞭解行業的發展,讓自己擴展出新的技能樹,對自己的職業發展還是

加速ASP.NET Core WEB API應用程式——第2部分

目錄 應用程式生產力 非同步設計模式 資料規範化與SQL查詢效率 NCHAR與NVARCHAR 使用MSSQL伺服器的全文引擎 儲存過程 優化儲存過程 預編譯和重用儲存過程執行計劃 使用Entity Framework Core進行全文搜尋 Entity

加速ASP.NET Core WEB API應用程式——第1部分

目錄 介紹 建立測試RESTful WEB API服務 應用程式架構 資料庫 建立ASP.NET核心WEB API應用程式 使用實體框架核心進行資料庫訪問 非同步設計模式 儲存庫 儲存庫實現 服務 服務介面 服務的實現 產品和價格表之間的資料完

【譯】使用Jwt身份認證保護 Asp Net Core Web Api

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

ASP.NET Core Web API 索引 (更新ASPNET Core和EF Core視訊)

GraphQL [視訊] 使用ASP.NET Core 開發 GraphQL 伺服器  GraphQL其它 RESTful API Identity Server 4 Identity Server 4 - Hybrid Flow ASP.NET Core

ASP.NET Core Web API 專案裡無法訪問(wwwroot)下的檔案

解決辦法:在“ Startup.cs ” 檔案裡的 Configur方法裡新增一句程式碼“ app.UseStaticFiles() ”,這樣就可以訪問wwwroot下的檔案了。 - 方法程式碼是

Gitlab CI 自動部署 asp.net core web api 到Docker容器

然後可以到官網下載net core 1.1 on MacOS,完成之後可以在命令列輸入 dotnet --version 來檢測當前的版本。 初始化專案並執行 通過3個命領我們可以完成初始化專案並執行的全過程: dotnet new|restore|run。 dotnet 框架預設提供一些初始化的專案模板,

支援多個版本的ASP.NET Core Web API

基本配置及說明 版本控制有助於及時推出功能,而不會破壞現有系統。 它還可以幫助為選定的客戶提供額外的功能。 API版本可以通過不同的方式完成,例如在URL中新增版本或通過自定義標頭和通過Accept-Header作為查詢字串引數。 在這篇文章中,我們來看看如何支援多版本的A

ASP.NET Core Web API下事件驅動型架構的實現(一):一個簡單的實現

很長一段時間以來,我都在思考如何在ASP.NET Core的框架下,實現一套完整的事件驅動型架構

Advanced Architecture for ASP.NET Core Web API

rom called too long chan odr nbsp ash libraries fun 轉自: https://www.infoq.com/articles/advanced-architecture-aspnet-core ASP.NET Co

ASP.NET Core Web API + Angular 仿B站(二)後臺模型創建以及數據庫的初始化

[] let 查看 hang lar enc cep 連接字符串 nds 前言: 本系列文章主要為對所學 Angular 框架的一次微小的實踐,對 b站頁面作簡單的模仿。 本系列文章主要參考資料: 微軟文檔:    https://docs.microsoft.com