泛型方法的单元测试
可以生成泛型方法的单元测试,用于其他方法执行,如中所 如何:创建和运行单元测试述。 以下各节提供有关信息,并创建单元测试的示例针对泛型方法。
类型参数和类型约束
当 Visual Studio 生成单元测试时泛型类,例如 MyList<T>,将生成两个方法:一个泛型 helper 和测试方法。 如果 MyList<T> 具有一个或多个类型约束,类型参数必须满足所有类型约束。 若要确保,泛型代码下测试按预期方式工作。所有允许输入的,测试方法调用与要测试的所有约束的泛型帮助器方法。
示例
下面的示例演示了泛型的单元测试:
编辑生成的测试代码。 此示例有两个部分,生成的测试代码,并编辑的测试代码。 此示例演示如何编辑原始测试从泛型方法生成为有用的测试方法代码。
使用类型约束。 此示例演示单元测试使用类型约束的泛型方法。 在此示例中,类型约束是不够的。
示例 1:编辑生成的测试代码
本节中的测试代码对名为 SizeOfLinkedList()的代码方法。 此方法返回指定节点个数连接表的整数。
第一个代码示例,在生成的测试代码 " 部分中,将没有编辑测试代码,它是由 Visual Studio 高级专业版 或 Visual Studio 旗舰版生成的。 第二个示例,在编辑的测试代码 " 部分中,演示如何会使其测试函数的两个不同数据类型、 int 和 char的 SizeOfLinkedList 方法。
此代码演示两种方法:
测试帮助器方法, SizeOfLinkedListTestHelper<T>()。 默认情况下,测试帮助器方法的名称中包含 TestHelper。
测试方法, SizeOfLinkedListTest()。 每个测试方法标有 TestMethod 特性。
生成的测试代码
下面的测试代码从 SizeOfLinkedList() 方法生成的。 由于这是未编辑的生成的该测试,则必须修改正确测试 SizeOfLinkedList 方法。
public void SizeOfLinkedListTestHelper<T>()
{
T val = default(T); // TODO: Initialize to an appropriate value
MyLinkedList<T> target = new MyLinkedList<T>(val); // TODO: Initialize to an appropriate value
int expected = 0; // TODO: Initialize to an appropriate value
int actual;
actual = target.SizeOfLinkedList();
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
[TestMethod()]
public void SizeOfLinkedListTest()
{
SizeOfLinkedListTestHelper<GenericParameterHelper>();
}
在上面的代码中,泛型类型参数是 GenericParameterHelper。 如下面的示例所示,而可以编辑它提供特定的数据类型,,可以运行测试,而无需编辑此语句。
编辑的测试代码
在下面的代码中,测试方法和测试帮助器方法编辑成功提交这些测试代码方法 SizeOfLinkedList()。
测试帮助器方法
测试帮助器方法执行以下步骤,这些步骤对应于的代码行标记为步骤 1。
创建泛型链接列表。
追加四个节点到连接表。 这些节点内容的数据类型未知。
分配预期范围的连接表与变量的 expected。
计算实际大小的连接表并将其分配给可变 actual。
actual 与断言语句的 expected 比较。 如果实际大小不等于预期大小,测试失败。
测试方法
测试方法编译到调用代码中,当您运行名为 SizeOfLinkedListTest 的测试时。 它执行以下步骤,这些步骤对应于的代码行已标记为步骤 6 和步骤。
指定 <int> ,调用测试帮助器方法时,验证 integer 变量的测试工作。
指定 <char> ,调用测试帮助器方法时,验证 char 变量的测试工作。
public void SizeOfLinkedListTestHelper<T>()
{
T val = default(T);
MyLinkedList<T> target = new MyLinkedList<T>(val); // step 1
for (int i = 0; i < 4; i++) // step 2
{
MyLinkedList<T> newNode = new MyLinkedList<T>(val);
target.Append(newNode);
}
int expected = 5; // step 3
int actual;
actual = target.SizeOfLinkedList(); // step 4
Assert.AreEqual(expected, actual); // step 5
}
[TestMethod()]
public void SizeOfLinkedListTest()
{
SizeOfLinkedListTestHelper<int>(); // step 6
SizeOfLinkedListTestHelper<char>(); // step 7
}
备注
每次运行 SizeOfLinkedListTest 测试时,对 TestHelper 方法调用两次。assert 语句必须计算为 true 时使测试通过。如果测试失败,可能不明确指定 <int> 或调用指定 <char> 的调用是否导致失败。若要找到答案,可以检查调用堆栈,还可以在测试方法中设置断点然后调试,以便在运行测试时。有关更多信息,请参见 如何:在 ASP.NET 解决方案中运行测试时进行调试。
示例 2:使用类型约束
此示例演示单元测试使用类型约束是不够的泛型方法。 从测试代码项目的第一部分演示代码。 该类型约束将突出显示。
从第二部分演示测试项目的代码。
测试代码项目
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
namespace ClassLibrary2
{
public class Employee
{
public Employee(string s, int i)
{
}
}
public class GenericList<T> where T : Employee
{
private class Node
{
private T data;
public T Data
{
get { return data; }
set { data = value; }
}
}
}
}
测试项目
与新生成的单元测试,必须将非没有结论的 assert 语句添加到此单元测试中以返回有用的结果。 您不会将其添加到标有 TestMethod 特性的方法,但对包含 TestHelper 方法,该方法在此测试名为 DataTestHelper<T>()。
在此示例中,泛型类型参数 T具有约束 where T : Employee。 此约束。测试方法没有足够。 因此, DataTest() 方法包含提示您需要提供类型约束。 T放置的一个 assert 语句。 此 assert 语句的消息如下: ("No appropriate type parameter is found to satisfies the type constraint(s) of T. " + "Please call DataTestHelper<T>() with appropriate type parameters.");
换言之,那么,当您从测试方法中调用 DataTestHelper<T>() 方法,DataTest(),必须通过类型 Employee 的参数或从 Employee派生的类。
using ClassLibrary2;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace TestProject1
{
[TestClass()]
public class GenericList_NodeTest
{
public void DataTestHelper<T>()
where T : Employee
{
GenericList_Shadow<T>.Node target = new GenericList_Shadow<T>.Node(); // TODO: Initialize to an appropriate value
T expected = default(T); // TODO: Initialize to an appropriate value
T actual;
target.Data = expected;
actual = target.Data;
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
[TestMethod()]
public void DataTest()
{
Assert.Inconclusive("No appropriate type parameter is found to satisfies the type constraint(s) of T. " +
"Please call DataTestHelper<T>() with appropriate type parameters.");
}
}
}