在 Visual Studio 2017 開發工具裡,建立單元測試專案有好幾種方法,其中一種是將現有專案增加一個相對應的單元測試專案。在傳統 .NET Framework 專案中,很輕易的就可以建立完成,只要在任一類別上按下滑鼠右鍵,選擇「建立單元測試」即可。但在 .NET Core 專案中就沒那麼方便了,因為這個功能一直沒被實現。本篇文章將分享如何依據現有專案的程式碼,產生相對應的單元測試專案,一步一步帶大家了解建立單元測試專案的過程。
從類別庫專案開始
首先,我們先建立一個 .NET Core 的「類別庫」專案 (Class Library),專案名稱假設為 ClassLibrary1,我們的專案中只有一個 MathLib 類別,且程式碼也相當簡單,只有 4 個方法 (Methods)。如下範例:
namespace ClassLibrary1
{
public class MathLib
{
public int Add(int a, int b)
{
return a + b;
}
public int Sub(int a, int b)
{
return a - b;
}
public int Mul(int a, int b)
{
return a * b;
}
public float Div(int a, int b)
{
return a / b;
}
}
}
加入單元測試專案
由於 Visual Studio 2017 目前還無法針對現有 .NET Core 專案方便的建立單元測試專案,所以步驟會稍微複雜一點。
-
我們先在現有方案中,手動建立一個全新的 xUnit 單元測試專案,專案名稱可命名為 ClassLibrary1Test。建立完成後,請先透過 NuGet 套件管理員將 xunit 相關套件升級到最新版本。
-
刪除預設的 UnitTest1.cs 檔案。
-
調整 ClassLibrary1Test 專案的相依性,將 ClassLibrary1 專案加入參考。
-
安裝 Unit Test Boilerplate Generator 擴充套件
- 請注意:這裡要安裝的不是 NuGet 套件喔!而是 Visual Studio 2017 的擴充套件!
- 安裝完成後,必須先關閉 Visual Studio 2017,安裝套件,再重開專案才行!
-
直接從方案總管選取 MathLib.cs 檔案,並按下滑鼠右鍵,選擇 Create Unit Test Boilerplate,然後在對話框中設定正確的單元測試專案、測試框架,以及想用的 Mock Framework,就可以自動產生測試類別/測試方法。

請注意:透過工具只會幫你大致寫好要測試的程式骨架(3A Pattern),事實上範例程式幾乎都不能用,還必須修改過才行。
-
修正程式碼
- 先移除
using NSubstitute; (因為目前用不到)
- 把所有
TODO 全部都改為 2
- 最後把
Assert.Fail(); 修正為 Assert.True(false); (全部都會測試失敗)
完成後的程式碼如下:
using ClassLibrary1;
using Xunit;
namespace ClassLibrary1Test
{
public class MathLibTests
{
public MathLibTests()
{
}
private MathLib CreateMathLib()
{
return new MathLib();
}
[Fact]
public void Add_StateUnderTest_ExpectedBehavior()
{
// Arrange
var unitUnderTest = CreateMathLib();
int a = 2;
int b = 2;
// Act
var result = unitUnderTest.Add(
a,
b);
// Assert
Assert.True(false);
}
[Fact]
public void Sub_StateUnderTest_ExpectedBehavior()
{
// Arrange
var unitUnderTest = CreateMathLib();
int a = 2;
int b = 2;
// Act
var result = unitUnderTest.Sub(
a,
b);
// Assert
Assert.True(false);
}
[Fact]
public void Mul_StateUnderTest_ExpectedBehavior()
{
// Arrange
var unitUnderTest = CreateMathLib();
int a = 2;
int b = 2;
// Act
var result = unitUnderTest.Mul(
a,
b);
// Assert
Assert.True(false);
}
[Fact]
public void Div_StateUnderTest_ExpectedBehavior()
{
// Arrange
var unitUnderTest = CreateMathLib();
int a = 2;
int b = 2;
// Act
var result = unitUnderTest.Div(
a,
b);
// Assert
Assert.True(false);
}
}
}
執行所有測試
-
從主選單找到 [測試] -> [視窗] -> [Test Explorer] 即可開啟測試總管
-
從主選單找到 [測試] -> [執行] -> [所有測試] 執行所有測試
如何測試私有類別
撰寫單元測試的時候,我們有時候會需要測試專案中的私有類別。我們先修改 MathLib.cs 類別檔,將 public class MathLib 改為 class MathLib,用來模擬私有類別的情況。
此時進行建置,你就會發現我們的 ClassLibrary1Test 單元測試專案已經無法看見 ClassLibrary1 專案中的 MathLib 類別了!

這個問題在單元測試專案中算是相當常見的,而且有標準的解決方法,那就是使用 InternalsVisibleToAttribute 進行宣告。
以前我們在建立 .NET Framework 專案時,都會有個 Properties\AssemblyInfo.cs 檔案。但是在 .NET Core 中,由於架構改變的關係,原本這個檔案的內容,大多已經搬到 *.csproj 專案檔中,所以這個檔案預設已經不存在了!
但在寫單元測試的時候,你只要把它加回來即可。請修改 ClassLibrary1 專案,加入 Properties\AssemblyInfo.cs 檔案,並設定成以下兩行內容:
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo(assemblyName: "ClassLibrary1Test")]
請注意:上述程式碼的 ClassLibrary1Test 字串,要設定為單元測試專案的組件名稱!
最後,我們只要再重建一次專案,就會發現單元測試專案已經可以成功建置與執行了!
相關連結