Xunit a une fonctionnalité intéressante : vous pouvez créer un test avec un Theory
attribut et mettre des données dans des InlineData
attributs, et xUnit générera de nombreux tests et les testera tous.
Je veux avoir quelque chose comme ça, mais les paramètres à ma méthode ne sont pas « données simples » (comme string
, int
, double
), mais une liste de ma classe:
public static void WriteReportsToMemoryStream(
IEnumerable<MyCustomClass> listReport,
MemoryStream ms,
StreamWriter writer) { ... }
c#
unit-testing
xunit
xunit.net
zchpit
la source
la source
Réponses:
Il existe de nombreux
xxxxData
attributs dans XUnit. Découvrez par exemple l'PropertyData
attribut.Vous pouvez implémenter une propriété qui retourne
IEnumerable<object[]>
. Chacunobject[]
que cette méthode génère sera ensuite "décompressé" en tant que paramètre pour un seul appel à votre[Theory]
méthode.Une autre option est
ClassData
, qui fonctionne de la même manière, mais permet de partager facilement les «générateurs» entre les tests dans différentes classes / espaces de noms, et sépare également les «générateurs de données» des méthodes de test réelles.Voir ie ces exemples à partir d'ici :
Exemple de PropertyData
Exemple ClassData
la source
static
. C'est exactement pourquoi je ne le ferais pas. ClassData est lorsque vous souhaitez échapper à la statique. Ce faisant, vous pouvez réutiliser (c'est-à-dire imbriquer) les générateurs plus facilement.[MemberData("{static member}", MemberType = typeof(MyClass))]
pour remplacer l'ClassData
attribut.nameof
mot - clé au lieu de coder en dur un nom de propriété (se brise facilement mais silencieusement).Pour mettre à jour la réponse de @ Quetzalcoatl: L'attribut
[PropertyData]
a été remplacé par[MemberData]
lequel prend comme argument le nom de chaîne de toute méthode statique, champ ou propriété qui renvoie unIEnumerable<object[]>
. (Je trouve particulièrement agréable d'avoir une méthode d'itération qui peut réellement calculer les cas de test un à la fois, les cédant au fur et à mesure qu'ils sont calculés.)Chaque élément de la séquence retournée par l'énumérateur est un
object[]
et chaque tableau doit avoir la même longueur et cette longueur doit être le nombre d'arguments de votre scénario de test (annoté avec l'attribut[MemberData]
et chaque élément doit avoir le même type que le paramètre de méthode correspondant (Ou peut-être qu'ils peuvent être des types convertibles, je ne sais pas.)(Voir les notes de publication de xUnit.net de mars 2014 et le correctif actuel avec un exemple de code .)
la source
La création de tableaux d'objets anonymes n'est pas le moyen le plus simple de construire les données, j'ai donc utilisé ce modèle dans mon projet
Définissez d'abord des classes partagées réutilisables
Désormais, votre test individuel et vos données de membre sont plus faciles à écrire et à nettoyer ...
La
Description
propriété string est de vous jeter un os lorsque l'un de vos nombreux cas de test échouela source
Supposons que nous ayons une classe de voiture complexe qui a une classe de fabricant:
Nous allons remplir et passer la classe Car à un test de théorie.
Créez donc une classe 'CarClassData' qui renvoie une instance de la classe Car comme ci-dessous:
Il est temps de créer une méthode de test (CarTest) et de définir la voiture comme paramètre:
Bonne chance
la source
Vous pouvez essayer de cette façon:
Créez une autre classe pour contenir les données de test:
la source
Pour mes besoins, je voulais juste lancer une série d '«utilisateurs de test» à travers quelques tests - mais [ClassData] etc. semblait exagéré pour ce dont j'avais besoin (car la liste des éléments était localisée à chaque test).
J'ai donc fait ce qui suit, avec un tableau à l'intérieur du test - indexé de l'extérieur:
Cela a atteint mon objectif, tout en gardant clairement l'intention du test. Il vous suffit de synchroniser les index, mais c'est tout.
Cela a l'air bien dans les résultats, il est pliable et vous pouvez réexécuter une instance spécifique si vous obtenez une erreur:
la source
MemberData
semble être que vous ne pouvez pas voir ni exécuter le test avec une entrée de test spécifique. Ça craint.MemberData
si vous utilisezTheoryData
et éventuellementIXunitSerializable
. Plus d'informations et d'exemples ici ... github.com/xunit/xunit/issues/429#issuecomment-108187109C'est ainsi que j'ai résolu votre problème, j'ai eu le même scénario. Donc en ligne avec des objets personnalisés et un nombre différent d'objets à chaque exécution.
C'est donc mon test unitaire, notez le paramètre params . Cela permet d'envoyer un nombre d'objets différent. Et maintenant ma classe DeviceTelemetryTestData :
J'espère que ça aide !
la source
Je suppose que vous vous êtes trompé ici. Ce que
Theory
signifie réellement l'attribut xUnit : Vous souhaitez tester cette fonction en envoyant des valeurs spéciales / aléatoires en tant que paramètres reçus par cette fonction sous test. Cela signifie que ce que vous définissez comme l'attribut suivant, par exemple:InlineData
,PropertyData
,ClassData
, etc .. seront la source de ces paramètres. Cela signifie que vous devez construire l'objet source pour fournir ces paramètres. Dans votre cas, je suppose que vous devriez utiliser l'ClassData
objet comme source. Aussi - veuillez noter queClassData
hérite de:IEnumerable<>
- cela signifie que chaque fois qu'un autre ensemble de paramètres générés sera utilisé comme paramètres entrants pour la fonction en cours de test jusqu'à ce queIEnumerable<>
produise des valeurs.Exemple ici: Tom DuPont .NET
L'exemple peut être incorrect - Je n'ai pas utilisé xUnit pendant une longue période
la source