{"id":"8bed9c5a-34d4-43da-a669-b5fd3f26dd1f","shortId":"Znf3Jc","kind":"skill","title":"dotnet-testing-advanced-aspnet-integration-testing","tagline":"ASP.NET Core 整合測試的專門技能。當需要測試 Web API 端點、HTTP 請求/回應、中介軟體、依賴注入時使用。涵蓋 WebApplicationFactory、TestServer、HttpClient 測試、記憶體資料庫配置等。\nMake sure to use this skill whenever the user mentions ASP.NET Core integration testing, WebApplicationFactory, TestServer, HTTP endpoint testing, or middl","description":"# ASP.NET Core 整合測試指南\n\n## 核心概念\n\n### 整合測試的兩種定義\n\n1. **多物件協作測試** — 將兩個以上的類別做整合，測試它們之間的運作是否正確\n2. **外部資源整合測試** — 使用到資料庫、外部服務、檔案等外部資源的測試\n\n### 為什麼需要整合測試？\n\n- 確保多個模組整合後能正確工作\n- 單元測試無法涵蓋的整合點：Routing、Middleware、Request/Response Pipeline\n- 確認 WebApplication 的整合與設定是否正確\n- 確認異常處理是否完善\n\n### 測試金字塔定位\n\n| 測試類型   | 測試範圍      | 執行速度 | 維護成本 | 建議比例 |\n| ---------- | ------------- | -------- | -------- | -------- |\n| 單元測試   | 單一類別/方法 | 很快     | 低       | 70%      |\n| 整合測試   | 多個元件      | 中等     | 中等     | 20%      |\n| 端對端測試 | 完整流程      | 慢       | 高       | 10%      |\n\n## 原則一：使用 WebApplicationFactory 建立測試環境\n\n透過 `WebApplicationFactory<Program>` 建立記憶體中的 TestServer，搭配 `IClassFixture` 在測試類別間共享。\n\n### 基本流程\n\n1. 測試類別實作 `IClassFixture<WebApplicationFactory<Program>>`\n2. 透過建構函式注入 Factory\n3. 使用 `factory.CreateClient()` 建立 HttpClient\n4. 對 API 端點發送請求並驗證回應\n\n### 自訂 Factory\n\n繼承 `WebApplicationFactory<Program>` 並覆寫 `ConfigureWebHost`：\n\n- 移除原本的 `DbContextOptions`，改用 `UseInMemoryDatabase`\n- 使用 `services.Replace()` 替換外部服務為測試版本\n- 設定 `builder.UseEnvironment(\"Testing\")` 使用測試環境\n\n### 測試基底類別\n\n建立 `IntegrationTestBase` 封裝共用邏輯：\n\n- Factory 與 HttpClient 初始化\n- `SeedShipperAsync()` 等資料準備方法\n- `CleanupDatabaseAsync()` 清理方法\n- 實作 `IDisposable` 確保資源釋放\n\n> 完整程式碼範例（基本使用、自訂 Factory、測試基底類別）請參考 [references/webapplicationfactory-examples.md](references/webapplicationfactory-examples.md)\n\n## 原則二：使用 AwesomeAssertions.Web 驗證 HTTP 回應\n\n提供流暢的 HTTP 狀態碼斷言與強型別回應驗證：\n\n- **狀態碼斷言**：`Be200Ok()`、`Be201Created()`、`Be400BadRequest()`、`Be404NotFound()` 等\n- **Satisfy<T> 驗證**：`response.Should().Be200Ok().And.Satisfy<T>(result => { ... })`\n- **優勢**：取代手動 `ReadAsStringAsync()` + `JsonSerializer.Deserialize<T>()` 的冗長程式碼\n\n## 原則三：使用 System.Net.Http.Json 簡化 JSON 操作\n\n- **`PostAsJsonAsync(url, object)`** — 取代手動 `JsonSerializer.Serialize` + `new StringContent`\n- **`ReadFromJsonAsync<T>()`** — 取代手動 `ReadAsStringAsync` + `JsonSerializer.Deserialize`\n\n> 完整斷言與 JSON 操作範例請參考 [references/assertion-and-json-examples.md](references/assertion-and-json-examples.md)\n\n## 三個層級的整合測試策略\n\n| Level | 特色                     | 測試重點                         | Factory 設定              |\n| ----- | ------------------------ | -------------------------------- | ------------------------- |\n| 1     | 無資料庫、無 Service     | API 輸入輸出、路由、狀態碼       | 直接使用原始 Factory      |\n| 2     | 有 Service（NSubstitute）| 依賴注入配置、服務互動           | ConfigureTestServices     |\n| 3     | 完整架構 + 資料庫        | 真實 CRUD、資料完整性            | InMemoryDatabase 替換     |\n\n### Level 1：簡單的 WebApi 專案\n\n最簡單的形式，直接使用 `WebApplicationFactory<Program>` 測試各個 API 端點的輸入輸出。\n\n### Level 2：相依 Service 的 WebApi 專案\n\n使用 NSubstitute 建立 Service stub，透過自訂 Factory 的 `ConfigureTestServices` 注入測試用服務。\n\n### Level 3：完整的 WebApi 專案\n\n包含真實的資料庫操作，移除原本的 `DbContextOptions` 並改用 InMemoryDatabase，在測試中呼叫 `EnsureCreated()` 建立結構。\n\n> 完整三個層級的程式碼範例請參考 [references/three-level-testing-strategy.md](references/three-level-testing-strategy.md)\n\n## CRUD 操作測試\n\n### 測試涵蓋範圍\n\n| 操作   | 測試重點                                       |\n| ------ | ---------------------------------------------- |\n| GET    | 單一資源查詢、集合查詢、不存在資源回傳 404     |\n| POST   | 建立成功回傳 201、驗證錯誤回傳 400             |\n| PUT    | 更新成功、不存在資源處理                       |\n| DELETE | 刪除成功回傳 204、不存在資源回傳 404           |\n\n### 測試資料管理\n\n- 每個測試開始前呼叫 `CleanupDatabaseAsync()` 確保乾淨狀態\n- 使用 `SeedShipperAsync()` 等方法準備測試資料\n- 使用 `Satisfy<T>()` 驗證回應內容的正確性\n\n完整的 CRUD 操作測試程式碼請參考 **[references/crud-test-examples.md](references/crud-test-examples.md)**\n\n## 專案結構建議\n\n```text\ntests/\n├── Sample.WebApplication.UnitTests/           # 單元測試\n├── Sample.WebApplication.Integration.Tests/   # 整合測試\n│   ├── Controllers/                           # 控制器整合測試\n│   ├── Infrastructure/                        # 測試基礎設施\n│   │   └── CustomWebApplicationFactory.cs\n│   ├── IntegrationTestBase.cs                 # 測試基底類別\n│   └── GlobalUsings.cs\n└── Sample.WebApplication.E2ETests/            # 端對端測試\n```\n\n## 常見錯誤排除\n\n### `'ObjectAssertions' 未包含 'Be200Ok' 的定義`\n\n此錯誤通常是因為安裝了不相容的斷言套件組合。請確認基礎斷言庫與 Web 擴充套件版本一致。\n\n### `Program` 類別無法存取\n\n確保主專案的 `Program.cs` 包含以下宣告，讓測試專案可以存取：\n\n```csharp\npublic partial class Program { }\n```\n\n### 測試資料互相干擾\n\n- 每個測試開始前清理資料庫\n- 不要依賴其他測試的執行順序\n- 使用唯一識別碼避免資料衝突\n\n## 套件相容性\n\n| 基礎斷言庫                 | 正確的套件              |\n| -------------------------- | ----------------------- |\n| FluentAssertions < 8.0.0   | FluentAssertions.Web    |\n| FluentAssertions >= 8.0.0  | FluentAssertions.Web.v8 |\n| AwesomeAssertions >= 8.0.0 | AwesomeAssertions.Web   |\n\n```xml\n<!-- 推薦組合 -->\n<PackageReference Include=\"AwesomeAssertions\" Version=\"9.4.0\" />\n<PackageReference Include=\"AwesomeAssertions.Web\" Version=\"1.9.6\" />\n```\n\n## 最佳實踐\n\n### 應該做\n\n1. **獨立測試專案** — 整合測試與單元測試分離\n2. **測試資料隔離** — 每個測試案例有獨立的資料準備和清理\n3. **使用基底類別** — 共用設定和輔助方法放在基底類別\n4. **明確的命名** — 使用三段式命名法（方法_情境_預期）\n5. **適當的測試範圍** — 專注於整合點，不過度測試\n\n### 應該避免\n\n1. **混合測試類型** — 不要將單元測試和整合測試放在同一專案\n2. **測試相依性** — 每個測試應獨立，不依賴其他測試的執行順序\n3. **過度模擬** — 整合測試應盡量使用真實元件\n4. **忽略清理** — 測試完成後要清理測試資料\n5. **硬編碼資料** — 使用工廠方法或 Builder 模式建立測試資料\n\n## 輸出格式\n\n- 產生 `CustomWebApplicationFactory.cs`，配置測試用 DI 容器與資料庫替換\n- 產生 `IntegrationTestBase.cs` 測試基底類別，包含資料準備與清理方法\n- 產生控制器測試類別（`*ControllerTests.cs`），涵蓋 CRUD 操作驗證\n- 修改測試專案 `.csproj`，加入 `Microsoft.AspNetCore.Mvc.Testing` 與 `AwesomeAssertions.Web`\n- 確保主專案 `Program.cs` 包含 `public partial class Program { }` 以支援測試存取\n\n## 參考資源\n\n### 原始文章\n\n- **Day 19 - 整合測試入門：基礎架構與應用場景**\n  - 鐵人賽文章：https://ithelp.ithome.com.tw/articles/10376335\n  - 範例程式碼：https://github.com/kevintsengtw/30Days_in_Testing_Samples/tree/main/day19\n\n### 官方文件\n\n- [ASP.NET Core 整合測試文件](https://docs.microsoft.com/aspnet/core/test/integration-tests)\n- [WebApplicationFactory 使用指南](https://docs.microsoft.com/aspnet/core/test/integration-tests#basic-tests-with-the-default-webapplicationfactory)\n- [AwesomeAssertions.Web GitHub](https://github.com/AwesomeAssertions/AwesomeAssertions.Web)\n\n### 相關技能\n\n- `unit-test-fundamentals` - 單元測試基礎\n- `nsubstitute-mocking` - 使用 NSubstitute 進行模擬\n- `awesome-assertions-guide` - AwesomeAssertions 流暢斷言\n- `testcontainers-database` - 使用 Testcontainers 進行容器化資料庫測試","tags":["dotnet","testing","advanced","aspnet","integration","agent","skills","kevintsengtw","agent-skills","ai-assisted-development","copilot-skills","csharp"],"capabilities":["skill","source-kevintsengtw","skill-dotnet-testing-advanced-aspnet-integration-testing","topic-agent-skills","topic-ai-assisted-development","topic-copilot-skills","topic-csharp","topic-dotnet","topic-dotnet-testing","topic-github-copilot","topic-integration-testing","topic-testing","topic-unit-testing","topic-xunit"],"categories":["dotnet-testing-agent-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/kevintsengtw/dotnet-testing-agent-skills/dotnet-testing-advanced-aspnet-integration-testing","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add kevintsengtw/dotnet-testing-agent-skills","source_repo":"https://github.com/kevintsengtw/dotnet-testing-agent-skills","install_from":"skills.sh"}},"qualityScore":"0.461","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 23 github stars · SKILL.md body (5,965 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-24T13:02:25.200Z","embedding":null,"createdAt":"2026-04-18T23:04:16.175Z","updatedAt":"2026-04-24T13:02:25.200Z","lastSeenAt":"2026-04-24T13:02:25.200Z","tsv":"'/articles/10376335':457 '/aspnet/core/test/integration-tests#basic-tests-with-the-default-webapplicationfactory)':473 '/aspnet/core/test/integration-tests)':468 '/awesomeassertions/awesomeassertions.web)':478 '/kevintsengtw/30days_in_testing_samples/tree/main/day19':461 '1':52,106,216,242,381,401 '10':93 '19':451 '2':56,110,226,253,384,404 '20':88 '201':297 '204':305 '3':113,233,270,387,408 '4':118,390,411 '400':299 '404':294,307 '5':396,414 '70':83 '8.0.0':369,372,376 'advanc':4 'and.satisfy':181 'api':13,120,220,250 'asp.net':8,36,47,463 'aspnet':5 'assert':493 'awesom':492 'awesome-assertions-guid':491 'awesomeassert':375,495 'awesomeassertions.web':164,377,439,474 'be200ok':172,180,344 'be201created':173 'be400badrequest':174 'be404notfound':175 'builder':417 'builder.useenvironment':136 'class':359,445 'cleanupdatabaseasync':149,310 'configuretestservic':232,267 'configurewebhost':127 'control':330 'controllertests.cs':430 'core':9,37,48,464 'crud':237,285,319,432 'csharp':356 'csproj':435 'customwebapplicationfactory.cs':334,421 'databas':499 'day':450 'dbcontextopt':129,276 'delet':303 'di':423 'docs.microsoft.com':467,472 'docs.microsoft.com/aspnet/core/test/integration-tests#basic-tests-with-the-default-webapplicationfactory)':471 'docs.microsoft.com/aspnet/core/test/integration-tests)':466 'dotnet':2 'dotnet-testing-advanced-aspnet-integration-test':1 'e2etests':339 'endpoint':43 'ensurecr':280 'factori':112,123,143,157,214,225,265 'factory.createclient':115 'fluentassert':368,371 'fluentassertions.web':370,373 'fundament':483 'get':290 'github':475 'github.com':460,477 'github.com/awesomeassertions/awesomeassertions.web)':476 'github.com/kevintsengtw/30days_in_testing_samples/tree/main/day19':459 'globalusings.cs':337 'guid':494 'http':15,42,166,169 'httpclient':23,117,145 'iclassfixtur':103,108 'idispos':152 'infrastructur':332 'inmemorydatabas':239,278 'integr':6,38 'integrationtestbas':141 'integrationtestbase.cs':335,426 'ithelp.ithome.com.tw':456 'ithelp.ithome.com.tw/articles/10376335':455 'json':192,206 'jsonserializer.deserialize':186,204 'jsonserializer.serialize':198 'level':211,241,252,269 'make':26 'mention':35 'microsoft.aspnetcore.mvc.testing':437 'middl':46 'middlewar':65 'mock':487 'new':199 'nsubstitut':229,260,486,489 'nsubstitute-mock':485 'object':196 'objectassert':342 'partial':358,444 'pipelin':67 'post':295 'postasjsonasync':194 'program':350,360,446 'program.cs':353,441 'public':357,443 'put':300 'readasstringasync':185,203 'readfromjsonasync':201 'references/assertion-and-json-examples.md':208,209 'references/crud-test-examples.md':321,322 'references/three-level-testing-strategy.md':283,284 'references/webapplicationfactory-examples.md':160,161 'request/response':66 'response.should':179 'result':182 'rout':64 'sample.webapplication':338 'sample.webapplication.integration.tests':328 'sample.webapplication.unittests':326 'satisfi':177,316 'seedshipperasync':147,313 'servic':219,228,255,262 'services.replace':133 'skill':31 'skill-dotnet-testing-advanced-aspnet-integration-testing' 'source-kevintsengtw' 'stringcont':200 'stub':263 'sure':27 'system.net.http.json':190 'test':3,7,39,44,137,325,482 'testcontain':498,501 'testcontainers-databas':497 'testserv':22,41,101 'text':324 'topic-agent-skills' 'topic-ai-assisted-development' 'topic-copilot-skills' 'topic-csharp' 'topic-dotnet' 'topic-dotnet-testing' 'topic-github-copilot' 'topic-integration-testing' 'topic-testing' 'topic-unit-testing' 'topic-xunit' 'unit':481 'unit-test-fundament':480 'url':195 'use':29 'useinmemorydatabas':131 'user':34 'v8':374 'web':12,348 'webapi':244,257,272 'webappl':69 'webapplicationfactori':21,40,96,99,109,125,248,469 'whenev':32 'xml':378 '三個層級的整合測試策略':210 '不依賴其他測試的執行順序':407 '不存在資源回傳':293,306 '不存在資源處理':302 '不要依賴其他測試的執行順序':363 '不要將單元測試和整合測試放在同一專案':403 '不過度測試':399 '並改用':277 '並覆寫':126 '中介軟體':18 '中等':86,87 '以支援測試存取':447 '低':82 '使用':95,114,132,163,189,259,312,315,488,500 '使用三段式命名法':392 '使用到資料庫':58 '使用唯一識別碼避免資料衝突':364 '使用基底類別':388 '使用工廠方法或':416 '使用指南':470 '使用測試環境':138 '依賴注入時使用':19 '依賴注入配置':230 '修改測試專案':434 '優勢':183 '共用設定和輔助方法放在基底類別':389 '初始化':146 '刪除成功回傳':304 '加入':436 '包含':442 '包含以下宣告':354 '包含真實的資料庫操作':274 '包含資料準備與清理方法':428 '原則一':94 '原則三':188 '原則二':162 '原始文章':449 '參考資源':448 '取代手動':184,197,202 '單一資源查詢':291 '單一類別':79 '單元測試':78,327 '單元測試基礎':484 '單元測試無法涵蓋的整合點':63 '回應':17,167 '在測試中呼叫':279 '在測試類別間共享':104 '執行速度':75 '基本使用':155 '基本流程':105 '基礎斷言庫':366 '基礎架構與應用場景':453 '外部服務':59 '外部資源整合測試':57 '多個元件':85 '多物件協作測試':53 '套件相容性':365 '完整三個層級的程式碼範例請參考':282 '完整斷言與':205 '完整架構':234 '完整流程':90 '完整的':271,318 '完整程式碼範例':154 '官方文件':462 '容器與資料庫替換':424 '實作':151 '封裝共用邏輯':142 '將兩個以上的類別做整合':54 '專案':245,258,273 '專案結構建議':323 '專注於整合點':398 '對':119 '常見錯誤排除':341 '建立':116,140,261 '建立成功回傳':296 '建立測試環境':97 '建立結構':281 '建立記憶體中的':100 '建議比例':77 '很快':81 '忽略清理':412 '情境':394 '慢':91 '應該做':380 '應該避免':400 '控制器整合測試':331 '提供流暢的':168 '搭配':102 '操作':193,288 '操作測試':286 '操作測試程式碼請參考':320 '操作範例請參考':207 '操作驗證':433 '擴充套件版本一致':349 '改用':130 '整合測試':84,329 '整合測試入門':452 '整合測試應盡量使用真實元件':410 '整合測試指南':49 '整合測試文件':465 '整合測試的兩種定義':51 '整合測試的專門技能':10 '整合測試與單元測試分離':383 '方法':80,393 '明確的命名':391 '更新成功':301 '替換':240 '替換外部服務為測試版本':134 '最佳實踐':379 '最簡單的形式':246 '有':227 '服務互動':231 '未包含':343 '核心概念':50 '模式建立測試資料':418 '檔案等外部資源的測試':60 '正確的套件':367 '此錯誤通常是因為安裝了不相容的斷言套件組合':346 '每個測試應獨立':406 '每個測試案例有獨立的資料準備和清理':386 '每個測試開始前呼叫':309 '每個測試開始前清理資料庫':362 '注入測試用服務':268 '流暢斷言':496 '涵蓋':20,431 '混合測試類型':402 '清理方法':150 '測試':24 '測試各個':249 '測試基底類別':139,158,336,427 '測試基礎設施':333 '測試它們之間的運作是否正確':55 '測試完成後要清理測試資料':413 '測試涵蓋範圍':287 '測試相依性':405 '測試範圍':74 '測試資料互相干擾':361 '測試資料管理':308 '測試資料隔離':385 '測試重點':213,289 '測試金字塔定位':72 '測試類別實作':107 '測試類型':73 '為什麼需要整合測試':61 '無':218 '無資料庫':217 '特色':212 '狀態碼':223 '狀態碼斷言':171 '狀態碼斷言與強型別回應驗證':170 '獨立測試專案':382 '產生':420,425 '產生控制器測試類別':429 '當需要測試':11 '的':256,266 '的冗長程式碼':187 '的定義':345 '的整合與設定是否正確':70 '直接使用':247 '直接使用原始':224 '相依':254 '相關技能':479 '真實':236 '硬編碼資料':415 '確保主專案':440 '確保主專案的':352 '確保乾淨狀態':311 '確保多個模組整合後能正確工作':62 '確保資源釋放':153 '確認':68 '確認異常處理是否完善':71 '移除原本的':128,275 '端對端測試':89,340 '端點':14 '端點發送請求並驗證回應':121 '端點的輸入輸出':251 '等':176 '等方法準備測試資料':314 '等資料準備方法':148 '範例程式碼':458 '簡化':191 '簡單的':243 '維護成本':76 '繼承':124 '自訂':122,156 '與':144,438 '記憶體資料庫配置等':25 '設定':135,215 '請參考':159 '請求':16 '請確認基礎斷言庫與':347 '讓測試專案可以存取':355 '資料完整性':238 '資料庫':235 '路由':222 '輸入輸出':221 '輸出格式':419 '透過':98 '透過建構函式注入':111 '透過自訂':264 '進行容器化資料庫測試':502 '進行模擬':490 '過度模擬':409 '適當的測試範圍':397 '配置測試用':422 '鐵人賽文章':454 '集合查詢':292 '預期':395 '類別無法存取':351 '驗證':165,178 '驗證回應內容的正確性':317 '驗證錯誤回傳':298 '高':92","prices":[{"id":"b768824d-0b29-4592-974c-c0791bcbafa4","listingId":"8bed9c5a-34d4-43da-a669-b5fd3f26dd1f","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"kevintsengtw","category":"dotnet-testing-agent-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T23:04:16.175Z"}],"sources":[{"listingId":"8bed9c5a-34d4-43da-a669-b5fd3f26dd1f","source":"github","sourceId":"kevintsengtw/dotnet-testing-agent-skills/dotnet-testing-advanced-aspnet-integration-testing","sourceUrl":"https://github.com/kevintsengtw/dotnet-testing-agent-skills/tree/main/skills/dotnet-testing-advanced-aspnet-integration-testing","isPrimary":false,"firstSeenAt":"2026-04-18T23:04:16.175Z","lastSeenAt":"2026-04-24T13:02:25.200Z"}],"details":{"listingId":"8bed9c5a-34d4-43da-a669-b5fd3f26dd1f","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"kevintsengtw","slug":"dotnet-testing-advanced-aspnet-integration-testing","github":{"repo":"kevintsengtw/dotnet-testing-agent-skills","stars":23,"topics":["agent-skills","ai-assisted-development","copilot-skills","csharp","dotnet","dotnet-testing","github-copilot","integration-testing","testing","unit-testing","xunit"],"license":"mit","html_url":"https://github.com/kevintsengtw/dotnet-testing-agent-skills","pushed_at":"2026-03-31T07:28:56Z","description":"AI Agent Skills for .NET Testing - Based on 30-Day Testing Challenge (iThome Ironman 2025 Winner)","skill_md_sha":"f5f199e0c3a95696f2dc9f96a1153115f4a2dc65","skill_md_path":"skills/dotnet-testing-advanced-aspnet-integration-testing/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/kevintsengtw/dotnet-testing-agent-skills/tree/main/skills/dotnet-testing-advanced-aspnet-integration-testing"},"layout":"multi","source":"github","category":"dotnet-testing-agent-skills","frontmatter":{"name":"dotnet-testing-advanced-aspnet-integration-testing","description":"ASP.NET Core 整合測試的專門技能。當需要測試 Web API 端點、HTTP 請求/回應、中介軟體、依賴注入時使用。涵蓋 WebApplicationFactory、TestServer、HttpClient 測試、記憶體資料庫配置等。\nMake sure to use this skill whenever the user mentions ASP.NET Core integration testing, WebApplicationFactory, TestServer, HTTP endpoint testing, or middleware testing, even if they don't explicitly ask for integration testing guidance.\nKeywords: integration testing, 整合測試, web api testing, WebApplicationFactory, TestServer, HttpClient testing, controller testing, endpoint testing, 端點測試, RESTful API testing, Microsoft.AspNetCore.Mvc.Testing, CreateClient, ConfigureWebHost, AwesomeAssertions.Web, Be200Ok, Be404NotFound, middleware testing, 中介軟體測試, dependency injection testing"},"skills_sh_url":"https://skills.sh/kevintsengtw/dotnet-testing-agent-skills/dotnet-testing-advanced-aspnet-integration-testing"},"updatedAt":"2026-04-24T13:02:25.200Z"}}