使用GitHub Copilot協助撰寫Blazor Server應用程式 - 2
本文將延續本站文章《使用GitHub Copilot協助撰寫Blazor Server應用程式 - 1》一文的情境,介紹如何在Visual Studio Code開發工具使用GitHub Copilot與其進階功能代理模式(Agent Mode) 來開發 ASP.NET Core Blazor Server 專案,讓開發者能以自然語言與 AI 對話,從專案建立、元件設計、Web API 撰寫到單元測試與除錯,全程自動化完成,展現出生成式 AI輔助設計的強大潛力與高效率。
在上一篇文章中,我們使用GitHub Copilot 代理模式(Agent Mode)設計模型(Models)與Web API控制器,接下來就來談談如何撰寫測試程式碼、設計Blazor元件以及發生錯誤時,如何引導AI協助解決錯誤。
撰寫測試程式碼
首先讓我們要求GitHub Copilot 代理模式(Agent Mode)來幫助撰寫「EmployeesController」類別的單元測試程式碼。目前Web API控制器的程式碼如下列:
EmployeesController.cs
using
Microsoft.AspNetCore.Mvc;
using
BlazorDemo.Models;
namespace BlazorDemo.Controllers
{
///
<summary>
/// 員工資料 API
控制器
///
</summary>
[ApiController]
[Route( "api/[controller]" )]
public class EmployeesController :
ControllerBase
{
private static readonly
List<Employee> _employees = new()
{
new Employee
{
Id = 1,
Name = "張小明",
Email = "xiaoming.zhang@example.com"
},
new Employee
{
Id = 2,
Name = "李美玲",
Email = "meiling.li@example.com"
},
new Employee
{
Id = 3,
Name = "王大同",
Email = "datong.wang@example.com"
}
};
/// <summary>
/// 取得所有員工資料
/// </summary>
/// <returns>員工資料清單</returns>
[HttpGet]
public
ActionResult<IEnumerable<Employee>> Get()
{
return Ok( _employees );
}
}
}
Visual
Studio Code開發工具Chat視窗加入提示如下:
使用 xUnit 撰寫測試,驗證錯誤處理是否正確運作
為每項變更撰寫文件。
在Chat視窗使用「Add Context」功能加入「EmployeesController」類別,然後執行提示:
圖 1:撰寫測試程式碼
執行的結果請參考下圖所示:
圖 2:撰寫測試程式碼執行的結果
GitHub
Copilot 代理模式(Agent
Mode)也會自動跑完單元測試,測試結果參考如下:
圖 3:單元測試的測試結果
檢視Visual Studio Code工具檔案總管視窗,可以看到GitHub Copilot代理模式(Agent Mode)產生了一個新的測試專案與測試程式碼,請參考下圖所示:
圖 4:GitHub Copilot代理模式(Agent
Mode)產生了新的測試專案與測試程式碼
產生的「EmployeesControllerTests.cs」程式如下所列:
EmployeesControllerTests.cs
using
System.Collections.Generic;
using
BlazorDemo.Controllers;
using
BlazorDemo.Models;
using
Microsoft.AspNetCore.Mvc;
using
Xunit;
namespace BlazorDemo.Tests
{
///
<summary>
///
EmployeesController 單元測試
///
</summary>
public class EmployeesControllerTests
{
private readonly
EmployeesController _controller;
public
EmployeesControllerTests()
{
_controller = new EmployeesController();
}
[Fact( DisplayName = "Get 方法應回傳所有員工資料" )]
public void
Get_ReturnsAllEmployees()
{
// Arrange & Act
var result =
_controller.Get();
// Assert
var okResult =
Assert.IsType<OkObjectResult>( result.Result );
var employees =
Assert.IsAssignableFrom<IEnumerable<Employee>>( okResult.Value );
Assert.NotEmpty( employees );
}
[Fact(DisplayName = "確認回傳的員工資料內容正確")]
public void
Get_ReturnsCorrectEmployeeData()
{
// Arrange & Act
var result =
_controller.Get();
// Assert
var okResult =
Assert.IsType<OkObjectResult>( result.Result );
var employees =
Assert.IsAssignableFrom<IEnumerable<Employee>>( okResult.Value );
var employeeList =
employees.ToList();
Assert.Equal( 3, employeeList.Count );
Assert.Contains( employeeList, e => e.Id == 1 && e.Name == "張小明" );
Assert.Contains( employeeList, e => e.Id == 2 && e.Name == "李美玲" );
Assert.Contains( employeeList, e => e.Id == 3 && e.Name == "王大同" );
}
[Fact(DisplayName = "確認回傳的狀態碼為 200
OK")]
public void
Get_ReturnsOkStatusCode()
{
// Arrange & Act
var result =
_controller.Get();
// Assert
var okResult =
Assert.IsType<OkObjectResult>( result.Result );
Assert.Equal( 200, okResult.StatusCode );
}
}
}
撰寫單元測試報告文件
GitHub
Copilot 代理模式(Agent
Mode)不僅可以幫您撰寫單元測試程式碼,也可以幫助撰寫單元測試報告文件,在Chat視窗加入提示如下:
將剛剛的測試結果的技術文件輸出成一份TestResult.md檔,Markdown格式,放在專案根目錄
執行的結果請參考下圖所示:
圖 5:撰寫單元測試報告文件
產生的「TestResult.md」檔案內容參考如下:
TestResult.md
# EmployeesController 單元測試報告
## 測試執行日期
2025-11-06
## 概述
此測試套件針對
`EmployeesController` 進行單元測試,確保其基本功能和錯誤處理機制正常運作。測試使用 xUnit 框架執行,涵蓋了主要的 API 功能和回應驗證。
## 測試案例詳細說明
### 1. Get_ReturnsAllEmployees
**目的**:驗證 GET 方法是否能正確返回所有員工資料
**驗證項目**:
- ✓ 回傳型別為 `OkObjectResult`
- ✓ 資料集合不為空
- ✓ 回傳型別符合 `IEnumerable<Employee>`
### 2. Get_ReturnsCorrectEmployeeData
**目的**:驗證回傳的員工資料內容正確性
**驗證項目**:
- ✓ 資料筆數為 3 筆
- ✓ 每筆資料的 Id 和
Name 符合預期
- ✓ 確認特定員工資料存在
- 張小明
(ID: 1)
- 李美玲
(ID: 2)
- 王大同
(ID: 3)
### 3. Get_ReturnsOkStatusCode
**目的**:驗證 API 回傳的 HTTP 狀態碼
**驗證項目**:
- ✓ 確認回傳狀態碼為 200 (OK)
- ✓ 驗證回傳結果型別
## 測試環境設置
- **測試框架**:xUnit
- **初始化方式**:建構函式中初始化控制器實例
- **資料處理**:使用靜態資料,無需 Mock 物件
## 建議的後續改進
### 優先度高
1. 新增錯誤處理的測試案例
- 無效的請求參數
- 資料驗證失敗情況
- 例外狀況處理
### 優先度中
2. 加入更多邊界條件測試
- 極限值測試
- 特殊字元處理
- 空值處理
### 優先度低
3. 考慮新增以下測試案例
- 資料驗證測試
- 非同步操作測試
- 效能測試
## 結論
所有測試案例均已通過,確保了 API
的基本功能正常運作。測試覆蓋了主要的使用場景,提供了程式碼品質的基本保障。建議根據後續改進建議持續擴充測試案例,以提高程式碼的穩定性和可靠性。
設計Blazor元件
最後我們來讓GitHub
Copilot代理模式(Agent Mode)設計Blazor元件當成使用者操作介面。在Chat視窗加入提示如下:
加入一個EmployeeList元件,叫用EmployeesController,取得所有Employee資料使用表格顯示之。
在選單加入一個連結以載入EmployeeList元件
執行的結果請參考下圖所示:
圖 6:設計Blazor元件
錯誤處理
在與GitHub Copilot 代理模式(Agent Mode)互動的過程中當然不會每次都順利,有可能產生出有問題的程式碼,若執行出錯該如何處理呢?例如筆者在設計Blazor元件的過程中發生一個問題,當網站程式執行後,元件無法載入並顯示員工清單,一直停留在「載入中」的畫面,請參考下圖所示:
圖 7:執行錯誤畫面
我們可以讓GitHub Copilot 代理模式(Agent Mode)幫忙除錯,在Chat視窗中點選「Attach Context」按鈕加入「Problems」項目,請參考下圖所示:
圖 8:加入「Programs」項目協助除錯
然後繼續加入懷疑有出問題的程式檔案,例如「EmployeeList.razor」;加入上圖執行出錯的截圖畫面,然後加入「/fix」斜線命令,撰寫提示如下:
/fix 執行後EmployeeList沒有顯示員工清單
請參考下圖所示:
圖 9:修訂程式問題
GitHub Copilot修定後的執行的結果請參考下圖所示:
圖 10:修訂程式問題
經過幾回合的溝通,現在Blazor元件便能正常運作了,執行的結果請參考下圖所示:
圖 11:Blazor元件執行結果
最終產生的「EmployeeList.razor」元件程式碼參考如下:
EmployeeList.razor
@page
"/employees"
@using
BlazorDemo.Models
@inject HttpClient Http
<HeadContent>
<title> 員工清單
</title>
</HeadContent>
<h1>員工清單</h1>
@if
(employees == null)
{
<p> <em> 載入中... </em> </p>
}
else
{
<table class = "table">
<thead>
<tr>
<th> 編號 </th>
<th> 姓名 </th>
<th> Email </th>
</tr>
</thead>
<tbody>
@foreach ( var employee in employees )
{
<tr>
<td> @employee.Id </td>
<td> @employee.Name </td>
<td> @employee.Email </td>
</tr>
}
</tbody>
</table>
}
@code {
private Employee[]? employees;
protected override async Task OnInitializedAsync()
{
try
{
employees = await Http.GetFromJsonAsync<Employee[]>( "api/employees" );
}
catch (Exception ex)
{
Console.WriteLine( $"Error loading employees: {ex.Message}" );
// 顯示錯誤訊息在控制台,方便除錯
System.Diagnostics.Debug.WriteLine( $"Error loading employees:
{ex.Message}" );
}
}
}
GitHub Copilot在導覽選單「NavMenu.razor」程式檔案中加入一個「員工清單」連結:
NavMenu.razor
<div class = "top-row ps-3 navbar navbar-dark">
<div class = "container-fluid">
<a class = "navbar-brand" href = ""> BlazorDemo
</a>
</div>
</div>
<input type = "checkbox" title = "Navigation menu" class = "navbar-toggler" />
<div class = "nav-scrollable" onclick = "document.querySelector('.navbar-toggler').click()">
<nav class = "nav flex-column">
<div class = "nav-item px-3">
<NavLink class = "nav-link" href = "" Match = "NavLinkMatch.All">
<span class = "bi bi-house-door-fill-nav-menu" aria-hidden = "true"> </span> 首頁
</NavLink>
</div>
<div class = "nav-item px-3">
<NavLink class = "nav-link" href = "privacy">
<span class = "bi bi-shield-fill-nav-menu" aria-hidden = "true"> </span> 版權宣告
</NavLink>
</div>
<div class = "nav-item px-3">
<NavLink class = "nav-link" href = "employees">
<span class = "bi
bi-people-fill-nav-menu" aria-hidden = "true">
</span> 員工清單
</NavLink>
</div>
</nav>
</div>
最終產生的「Program.cs」檔案的程式碼參考如下,自動註冊「HttpClient」服務讓Blazor透過它叫用Web API取得員工清單來顯示:
Program.cs
using
BlazorDemo.Components;
var
builder = WebApplication.CreateBuilder(args);
// Add services to the
container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// 加入 HttpClient 服務
builder.Services.AddScoped(
sp => new HttpClient
{
BaseAddress = new Uri("http://localhost:5086")
});
// 加入 Web
API 服務
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
var
app = builder.Build();
// Configure the HTTP request
pipeline.
if
(!app.Environment.IsDevelopment())
{
app.UseExceptionHandler( "/Error",
createScopeForErrors: true );
// The default
HSTS value is 30 days. You may want to change this for production scenarios,
see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseAntiforgery();
app.MapStaticAssets();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
// 加入 Web
API 路由映射
app.MapControllers();
app.Run();
工作流程圖
最後,對於複雜的專案我們可以請GitHub
Copilot 代理模式(Agent
Mode)繪製圖表來說明,在Chat視窗加入提示如下:
建立應用程式的工作流程圖
執行的結果請參考下圖所示:
圖 12:產生工作流程圖
參考產生的「Workflow.md」檔案內容如下:
Workflow.md
# Blazor Server 應用程式工作流程圖
以下以繁體中文說明 Blazor
Server 應用程式的主要執行流程,並提供一個
Mermaid 工作流程圖,說明從啟動到 UI 顯示、資料取得與靜態資源的處理路徑。
## 快速說明
- 平台:ASP.NET Core 9.0 / Blazor Server
- 主要檔案:`Program.cs`(啟動、服務註冊)、`Components/Pages/*.razor`(頁面元件)、`Controllers/EmployeesController.cs`(API 控制器)、`Models/Employee.cs`(資料模型)、`wwwroot/`(靜態資源)
- 通訊:Blazor Server 使用 SignalR 維持 client 與 server 的
circuit;頁面內若使用 HttpClient
呼叫 API,則透過標準 HTTP pipeline。
## Mermaid 工作流程圖
```mermaid
flowchart TD
A[啟動: Program.cs] --> B[服務註冊 (DI, HttpClient, DbContext...)]
B --> C[建立 HTTP Pipeline (Routing, Endpoints, Static Files)]
C --> D[靜態資源: wwwroot -> 瀏覽器]
subgraph Blazor_Server
E[瀏覽器連線 (SignalR)] --> F[建立 Circuit]
F --> G[Render Root Component
(App.razor)]
G --> H[Layout (MainLayout,
NavMenu)]
H --> I[Page 元件 (例如: EmployeeList.razor)]
I --> J{是否需呼叫 API}
J -- 是 --> K[HttpClient 呼叫 /api/employees]
K -->
L[EmployeesController](controller)
L --> M[Business / Data
(Models/Employee 或
DB)]
M --> N[回傳 JSON 結果]
N --> I
J -- 否 --> O[直接在元件內使用 injected service 或 state]
end
%% 顯示資料流程回到 UI
N --> P[元件接收資料並 Render/re-render]
%% 例外與錯誤處理
L --> Q[錯誤處理 (返回
4xx/5xx)]
Q --> I
style Blazor_Server
fill:#f9f,stroke:#333,stroke-width:1px
```
## 流程文字版(步驟)
1. 程式啟動:`Program.cs` 設定服務 (dependency injection)、註冊 `HttpClient`、資料庫上下文或其他服務。
2. 建立 HTTP pipeline:middleware(靜態檔案、路由、端點)。
3. 使用者透過瀏覽器開啟網站,瀏覽器與 Server 建立 SignalR 連線(Blazor Server),建立一個 Circuit。
4.
Server 在 Circuit 內渲染 Root component (`App.razor`),載入 `MainLayout` 與 `NavMenu`。
5. 使用者導航到頁面(例如 `/employees`),相對應的 `.razor` 元件被渲染(`EmployeeList.razor`)。
6. 若元件需要外部資料:它會透過注入的 `HttpClient` 呼叫 API(例如 `EmployeesController`),或直接注入一個資料服務。
7.
API Controller (`EmployeesController`) 讀取 `Models/Employee` 或資料庫並回傳 JSON 給元件。
8. 元件接收資料並更新 UI(Blazor 將觸發 re-render),同時維持 SignalR circuit 的連線狀態。
9. 靜態資源(CSS/JS)由 `wwwroot` 提供給瀏覽器;開發環境常用 `dotnet run` 啟動並可在本機檢視。
## 範例:EmployeeList 資料流(簡化)
- 使用者 -> 瀏覽器 -> Server (SignalR)
-
EmployeeList.razor 呼叫
HttpClient -> /api/employees
-
EmployeesController 拿到資料
-> 回傳 JSON
-
EmployeeList 收到
JSON -> Render 表格
## 檔案與檢視建議
- 檔案位置:`BlazorDemo/Docs/Workflow.md`(本檔)
- 在 VS Code 中可直接打開並用 Markdown Preview (Ctrl+Shift+V) 查看 Mermaid 圖(需安裝支援 Mermaid 的擴充套件,如 "Markdown Preview Mermaid Support")。
- 若要在專案內直接產生 SVG,建議使用外部工具或 VS Code 擴充功能匯出。
## 下一步建議
- 若需要,我可以把這張圖匯出為 SVG 檔並新增到 `wwwroot/docs/` 以便於瀏覽與列印。
- 我也能把流程轉成順序圖或更詳細的資料流圖(帶類別或端點呼叫),或產生簡短的
README 摘要。
---
檔案由自動化工具建立。如需調整內容或增加更細的流程圖(例如 DB schema、Auth
流程、SignalR 詳細時序),請告訴我想要的細節。
其中有使用Mermaid描述的流程圖。在Chat視窗加入提示如下,將繪製的Mermaid流程圖轉成SVG格式:
Mermaid 匯出成 SVG 並放到根目錄 ,檔名:workflow.svg
然後您就有詳細的專案運作流程圖可以參考了,執行的結果請參考下圖所示:
圖 13:Mermaid流程圖轉成SVG格式
總結

0 意見:
張貼留言