Xunit hat eine nette Funktion : Sie können einen Test mit einem Theory
Attribut erstellen und Daten in InlineData
Attribute einfügen , und xUnit generiert viele Tests und testet sie alle.
Ich möchte so etwas haben, aber die Parameter auf meine Methode nicht ‚einfach Daten‘ (wie string
, int
, double
), aber eine Liste meiner Klasse:
public static void WriteReportsToMemoryStream(
IEnumerable<MyCustomClass> listReport,
MemoryStream ms,
StreamWriter writer) { ... }
c#
unit-testing
xunit
xunit.net
zchpit
quelle
quelle
Antworten:
xxxxData
In XUnit gibt es viele Attribute. Schauen Sie sich zum Beispiel dasPropertyData
Attribut an.Sie können eine Eigenschaft implementieren, die zurückgibt
IEnumerable<object[]>
. Jedesobject[]
, das diese Methode generiert, wird dann als Parameter für einen einzelnen Aufruf Ihrer[Theory]
Methode "entpackt" .Eine andere Option ist
ClassData
, die gleich funktioniert, aber die einfache Freigabe der 'Generatoren' zwischen Tests in verschiedenen Klassen / Namespaces ermöglicht und auch die 'Datengeneratoren' von den tatsächlichen Testmethoden trennt.Siehe zB diese Beispiele von hier :
PropertyData-Beispiel
ClassData Beispiel
quelle
static
. Genau deshalb würde ich nicht. ClassData ist, wenn Sie der Statik entkommen möchten. Auf diese Weise können Sie die Generatoren einfacher wiederverwenden (dh verschachteln).[MemberData("{static member}", MemberType = typeof(MyClass))]
, um dasClassData
Attribut zu ersetzen .nameof
Schlüsselwort zu verwenden, anstatt einen Eigenschaftsnamen fest zu codieren (bricht leicht, aber lautlos ab).So aktualisieren Sie die Antwort von @ Quetzalcoatl: Das Attribut
[PropertyData]
wurde ersetzt, durch[MemberData]
das der Zeichenfolgenname einer statischen Methode, eines Felds oder einer Eigenschaft, die eine zurückgibt, als Argument verwendet wirdIEnumerable<object[]>
. (Ich finde es besonders schön, eine Iterator-Methode zu haben, mit der Testfälle einzeln berechnet werden können, sodass sie bei der Berechnung angezeigt werden.)Jedes Element in der vom Enumerator zurückgegebenen Sequenz ist ein
object[]
und jedes Array muss dieselbe Länge haben und diese Länge muss die Anzahl der Argumente für Ihren Testfall sein (mit dem Attribut versehen[MemberData]
und jedes Element muss denselben Typ wie der entsprechende Methodenparameter haben (Oder vielleicht können es konvertierbare Typen sein, ich weiß es nicht.)(Siehe Versionshinweise für xUnit.net März 2014 und den aktuellen Patch mit Beispielcode .)
quelle
Das Erstellen anonymer Objektarrays ist nicht der einfachste Weg, um die Daten zu erstellen. Daher habe ich dieses Muster in meinem Projekt verwendet
Definieren Sie zunächst einige wiederverwendbare, gemeinsam genutzte Klassen
Jetzt sind Ihre individuellen Test- und Mitgliedsdaten einfacher zu schreiben und sauberer ...
Die
Description
Eigenschaft string besteht darin, sich einen Knochen zuzuwerfen, wenn einer Ihrer vielen Testfälle fehlschlägtquelle
Angenommen, wir haben eine komplexe Fahrzeugklasse mit einer Herstellerklasse:
Wir werden die Autoklasse füllen und einem Theorie-Test unterziehen.
Erstellen Sie also eine 'CarClassData'-Klasse, die eine Instanz der Car-Klasse wie folgt zurückgibt:
Es ist Zeit, eine Testmethode (CarTest) zu erstellen und das Auto als Parameter zu definieren:
Viel Glück
quelle
Sie können dies folgendermaßen versuchen:
Erstellen Sie eine weitere Klasse für die Testdaten:
quelle
Für meine Bedürfnisse wollte ich nur eine Reihe von 'Testbenutzern' durch einige Tests führen - aber [ClassData] usw. schienen für das, was ich brauchte, übertrieben (da die Liste der Elemente für jeden Test lokalisiert war).
Also habe ich Folgendes mit einem Array innerhalb des Tests gemacht - von außen indiziert:
Dies hat mein Ziel erreicht und gleichzeitig die Absicht des Tests klar gehalten. Sie müssen nur die Indizes synchron halten, aber das ist alles.
Sieht in den Ergebnissen gut aus, ist reduzierbar und Sie können eine bestimmte Instanz erneut ausführen, wenn Sie eine Fehlermeldung erhalten:
quelle
MemberData
scheint zu sein, dass Sie den Test mit einer bestimmten Testeingabe nicht sehen oder ausführen können. Es nervt.MemberData
wenn SieTheoryData
und optional verwendenIXunitSerializable
. Weitere Infos und Beispiele hier ... github.com/xunit/xunit/issues/429#issuecomment-108187109So habe ich Ihr Problem gelöst, ich hatte das gleiche Szenario. Also inline mit benutzerdefinierten Objekten und einer anderen Anzahl von Objekten bei jedem Lauf.
Dies ist also mein Komponententest . Beachten Sie den Parameter params . Dies ermöglicht das Senden einer anderen Anzahl von Objekten. Und jetzt meine DeviceTelemetryTestData- Klasse:
Ich hoffe es hilft !
quelle
Ich denke du hast dich hier geirrt. Was das xUnit-
Theory
Attribut tatsächlich bedeutet: Sie möchten diese Funktion testen, indem Sie spezielle / zufällige Werte als Parameter senden, die diese zu testende Funktion empfängt. Das bedeutet , dass , was Sie als nächstes Attribut definieren, wie zum Beispiel:InlineData
,PropertyData
,ClassData
, etc .. wird die Quelle für diese Parameter sein. Das bedeutet, dass Sie das Quellobjekt erstellen sollten, um diese Parameter bereitzustellen. In Ihrem Fall sollten Sie dasClassData
Objekt als Quelle verwenden. Beachten Sie außerdemClassData
Folgendes:IEnumerable<>
- Dies bedeutet, dass jedes Mal ein anderer Satz generierter Parameter als eingehende Parameter für die zu testende Funktion verwendet wird, bisIEnumerable<>
Werte erzeugt werden.Beispiel hier: Tom DuPont .NET
Beispiel kann falsch sein - ich habe xUnit lange nicht benutzt
quelle