首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Visual Studio 2012 單元測試泛型類完整指南:一般泛型與型別約束測試模式

     編輯:關於.NET

泛型單元測試核心挑戰

測試泛型方法需驗證多種型別引數,手寫重複測試碼違反 DRY 原則。VS2012 提供 Microsoft.VisualStudio.TestTools.UnitTesting.GenericParameterHelper 作為預設型別引數,但型別約束泛型 (如 where T : struct) 需自訂測試協助類。

案例一:無型別約束泛型測試

被測方法

public static bool IsCollectionEmpty<T>(ICollection<T> collection)
{
    return collection == null || collection.Count < 1;
}

測試模式:泛型輔助方法 + 具象化測試方法

public void IsCollectionEmptyTestHelper<T>()
{
    // Case 1: 非空集合
    ICollection<T> collection = new T[] { default(T) };
    Assert.IsFalse(UtilityCheckData.IsCollectionEmpty<T>(collection));

    // Case 2: 空集合
    collection = new T[] { };
    Assert.IsTrue(UtilityCheckData.IsCollectionEmpty<T>(collection));

    // Case 3: null
    Assert.IsTrue(UtilityCheckData.IsCollectionEmpty<T>(null));
}

[TestMethod]
public void IsCollectionEmptyTest()
{
    // 使用框架提供的 GenericParameterHelper 作為型別引數
    IsCollectionEmptyTestHelper<GenericParameterHelper>();
}

案例二:有型別約束泛型測試 (where T : struct)

被測類別:簡易堆疊

public class StackNum<T> where T : struct
{
    List<T> _array = new List<T>();
    public void Push(T value) { _array.Add(value); }
    public T Pop() { var v = _array[_array.Count - 1]; _array.RemoveAt(_array.Count - 1); return v; }
    public int Length { get { return _array.Count; } }
}

測試協助類 (封裝共同邏輯)

static class StackTestHelper
{
    public static void LengthTest<T>() where T : struct
    {
        var stack = new StackNum<T>();
        Assert.AreEqual(0, stack.Length);
    }

    public static void PushTest<T>() where T : struct
    {
        var stack = new StackNum<T>();
        stack.Push(default(T));
        Assert.AreEqual(1, stack.Length);
    }

    public static void PopTest<T>(params T[] values) where T : struct
    {
        var stack = new StackNum<T>();
        if (values == null) return;
        foreach (var v in values) { stack.Push(v); Assert.AreEqual(stack.Length, Array.IndexOf(values, v) + 1); }
        for (int i = values.Length - 1; i >= 0; i--)
        {
            Assert.AreEqual(values[i], stack.Pop());
            Assert.AreEqual(i, stack.Length);
        }
    }
}

具象化測試類別

[TestClass]
public class StackTest
{
    [TestMethod] public void PushTest() { StackTestHelper.PushTest<decimal>(); StackTestHelper.PushTest<double>(); }
    [TestMethod] public void PopTest() { StackTestHelper.PopTest<int>(22, 33, 55); StackTestHelper.PopTest<bool>(true, false); }
    [TestMethod] public void LengthTest() { StackTestHelper.LengthTest<char>(); }
}

進階技巧

  • 資料驅動測試:搭配 DataSource 屬性從 XML/CSV 讀取型別清單,動態建構測試。
  • 反射泛型化:透過 MethodInfo.MakeGenericMethod 於運行時組合測試案例。
  • 約束驗證:測試 where T : class, new() 等複合約束時,協助類需對應約束聲明。

總結

泛型單元測試關鍵在於「抽象測試邏輯 → 具象化型別引數」。無約束泛型用 GenericParameterHelper;有約束泛型自訂協助類並明確聲明 where 子句。良好的測試結構讓泛型程式碼品質可控、可維護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved