Komponententests für generische Methoden
Komponententests für generische Methoden können genauso wie für jede andere Methode generiert werden, wie in Gewusst wie: Erstellen und Ausführen eines Komponententests beschrieben. Die folgenden Abschnitte enthalten Informationen und Beispiele zum Erstellen von Komponententests für generische Methoden.
Typargumente und Typeinschränkungen
Wenn in Visual Studio ein Komponententest für eine generische Klasse wie MyList<T> generiert wird, entstehen zwei Methoden: eine generische Hilfsmethode und eine Testmethode. Wenn MyList<T> über eine oder mehrere Typeinschränkungen verfügt, muss das Typargument alle Typeinschränkungen erfüllen. Um sicherzustellen, dass der generische Code, der getestet wird, bei allen zulässigen Eingaben erwartungsgemäß funktioniert, ruft die Testmethode die generische Hilfsmethode mit allen Einschränkungen auf, die Sie testen möchten.
Beispiele
In den folgenden Beispielen werden Komponententests für Generika veranschaulicht:
Bearbeiten von generiertem Testcode. Dieses Beispiel weist zwei Abschnitte auf: Generierter Testcode und Bearbeiteter Testcode. Es zeigt, wie der von einer generischen Methode generierte Rohdaten-Testcode bearbeitet wird, um eine hilfreiche Testmethode zu erhalten.
Verwenden einer Typeinschränkung. In diesem Beispiel wird ein Komponententest für eine generische Methode veranschaulicht, die eine Typeinschränkung verwendet. In diesem Beispiel wird die Typeinschränkung nicht erfüllt.
Beispiel 1: Bearbeiten von generiertem Testcode
Im Testcode in diesem Abschnitt wird eine CUT (Code-unter-Test-)Methode mit dem Namen SizeOfLinkedList() getestet. Diese Methode gibt eine ganze Zahl zurück, die die Anzahl der Knoten in der verknüpften Liste angibt.
Das erste Codebeispiel im Abschnitt Generierter Testcode enthält den unbearbeiteten Testcode, wie von Visual Studio Premium oder Visual Studio Ultimate generiert. Das zweite Beispiel im Abschnitt Bearbeiteter Testcode veranschaulicht, wie Sie mit dem Code die Funktionsweise der SizeOfLinkedList-Methode für die beiden unterschiedlichen Datentypen int und char testen lassen können.
In diesem Code werden zwei Methoden veranschaulicht:
die Testhilfsmethode SizeOfLinkedListTestHelper<T>(). Der Name einer Testhilfsmethode enthält standardmäßig den Begriff "TestHelper".
die Testmethode SizeOfLinkedListTest(). Jede Testmethode wird mit dem TestMethod-Attribut markiert.
Generierter Testcode
Der folgende Testcode wurde von der SizeOfLinkedList()-Methode generiert. Da es sich hierbei um den unbearbeiteten, generierten Test handelt, muss er geändert werden, damit die SizeOfLinkedList-Methode ordnungsgemäß getestet wird.
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>();
}
Im vorangehenden Code lautet der generische Typparameter GenericParameterHelper. Obwohl der Parameter zur Angabe bestimmter Datentypen geändert werden kann, wie aus dem folgenden Beispiel ersichtlich, könnten Sie den Test ausführen, ohne diese Anweisung zu bearbeiten.
Bearbeiteter Testcode
Im folgenden Code wurde die Testmethode und Testhilfsmethode bearbeitet, damit die Code-unter-Test-Methode SizeOfLinkedList() erfolgreich von den Methoden getestet werden kann.
Testhilfsmethode
Die Testhilfsmethode führt die folgenden Schritte aus, die im Code den mit Schritt 1 bis 5 beschrifteten Zeilen entsprechen.
Erstellen einer generischen verknüpften Liste
Anfügen von vier Knoten an die verknüpfte Liste. Der Datentyp des Inhalts dieser Knoten ist unbekannt.
Zuweisen der erwarteten Größe der verknüpften Liste zur Variablen expected
Berechnen der tatsächlichen Größe der verknüpften Liste und Zuweisen der Größe zur Variablen actual
Vergleichen von actual mit expected in einer Assert-Anweisung. Wenn die tatsächliche (actual) nicht der erwarteten (expected) Größe entspricht, ist der Test nicht erfolgreich.
Testmethode
Die Testmethode wird in den Code kompiliert, der aufgerufen wird, wenn Sie den Test SizeOfLinkedListTest ausführen. Sie führt die folgenden Schritte aus, die im Code den mit Schritt 6 und 7 beschrifteten Zeilen entsprechen.
Festlegen von <int> beim Aufrufen der Testhilfsmethode, um sicherzustellen, dass der Test für integer-Variablen verwendet werden kann.
Festlegen von <char> beim Aufrufen der Testhilfsmethode, um sicherzustellen, dass der Test für char-Variablen verwendet werden kann.
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
}
Tipp
Bei jeder Ausführung des SizeOfLinkedListTest-Tests wird dessen TestHelper-Methode zweimal aufgerufen. Die Assert-Anweisung muss jedes Mal true ergeben, damit der Test erfolgreich verläuft. Wenn der Test fehlschlägt, ist u. U. nicht klar, ob der Fehler durch den Aufruf verursacht wurde, mit dem <int> angegeben wurde, oder durch den Aufruf, mit dem <char> angegeben wurde. Um dies herauszufinden, könnten Sie die Aufrufliste überprüfen oder Haltepunkte in der Testmethode festlegen und den Test während der Ausführung debuggen. Weitere Informationen finden Sie unter Gewusst wie: Debuggen beim Ausführen eines Tests in einer ASP.NET-Projektmappe.
Beispiel 2: Verwenden einer Typeinschränkung
In diesem Beispiel wird ein Komponententest für eine generische Methode veranschaulicht, die eine Typeinschränkung verwendet, die nicht erfüllt wird. Der erste Abschnitt enthält Code aus dem CUT (Code-unter-Test-)Projekt. Die Typeinschränkung ist hervorgehoben.
Der zweite Abschnitt enthält Code aus dem Testprojekt.
CUT (Code-unter-Test-)Projekt
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; }
}
}
}
}
Testprojekt
Wie bei allen neu generierten Komponententests müssen Sie diesem Komponententest eindeutige Assert-Anweisungen hinzufügen, damit er brauchbare Ergebnisse zurückgibt. Die Anweisungen werden nicht der mit dem TestMethod-Attribut markierten Methode hinzugefügt, sondern der "TestHelper"-Methode, die in diesem Test den Namen DataTestHelper<T>() hat.
In diesem Beispiel verfügt der generische Typparameter T über die Einschränkung where T : Employee. Diese Einschränkung wird in der Testmethode nicht erfüllt. Aus diesem Grund enthält die DataTest()-Methode eine Assert-Anweisung, die Sie darauf hinweist, dass die für T festgelegte Typeinschränkung bereitgestellt werden muss. Die Mitteilung in der Assert-Anweisung lautet wie folgt: ("No appropriate type parameter is found to satisfies the type constraint(s) of T. " + "Please call DataTestHelper<T>() with appropriate type parameters.");
Anders ausgedrückt bedeutet dies: Wenn Sie die DataTestHelper<T>()-Methode aus der Testmethode DataTest() aufrufen, müssen Sie einen Parameter des Typs Employee oder eine von Employee abgeleitete Klasse übergeben.
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.");
}
}
}