XUnit, AutoFixture et Moq les meilleures pratiques
Je suis en train de lire beaucoup de documentation et des exemples sur la façon de bien l'unité de tester des choses en combinant les trois composants dans le titre. Je suis venu avec une méthode d'essai pour la méthode sur mon entreprise logique, mais il se sent très maladroit et sale.
J'aimerais avoir quelques commentaires de gens plus expérimentés sur ce sujet, afin de voir comment je peux l'améliorer.
Voici le code, l'explication suivante:
[Fact]
public void ShouldGetItemWithSameId()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var facade = fixture.Freeze<Mock<IDataFacade>>();
facade.Setup(c => c.Get(It.IsAny<int>())).Returns((int i) => new Item { Key = i });
var sut = fixture.Create<BusinessLogic>();
var expected = fixture.Create<int>();
Assert.Equal(expected, sut.Get(expected).Key);
}
Mon BusinessLogic
de classe prend une IDataFacade
comme paramètre dans le constructeur, qui est responsable en sa Get(int)
méthode pour récupérer l'élément avec le même Id, jolis trucs de base.
- Je congeler le IDataFacade
maquette et je l'ai configuré pour construire un objet qui correspond à l'Id dans It.IsAny<int>
. J'ai ensuite créer mon SUT et le tester. Fonctionne très bien.
Je voudrais comprendre si je peux améliorer les choses en considérant les éléments suivants:
- Je dois tester des méthodes plus complexes, comme un
Query
méthode qui prend une classe contenant beaucoup de propriétés qui seront utilisées comme filtres sur les propriétés correspondantes sur le type qui est interrogée. Dans ce cas, je ne sais pas comment faire le "Setup" de la maquette, depuis que j'ai initialisation de tous les, ou à proximité de tous, les propriétés de l'retourné type, et dans ce scénario, il n'est pas un Élément unique, mais un ensemble de la collection - La partie configuration se sent à sa place, j'aimerais pouvoir la réutiliser dans plusieurs méthodes
J'ai d'autres tests à l'aide de Theory
avec AutoMoqData
mais j'ai été incapable de réaliser ce test (et je pense que les plus complexes) à l'aide de cette approche, j'ai donc changé de revenir à la plaine de Fact
avec manuellement instancié luminaire.
Toute aide sera très appréciée.
OriginalL'auteur Matteo Mosca | 2014-12-18
Vous devez vous connecter pour publier un commentaire.
Votre test semble bien pour moi, bien que je vous recommande un changement. La ligne suivante pourrait être serré jusqu'à retourner la valeur attendue si la valeur attendue est passé:
Tout vous devez faire déplacer la variable attendue et le changement de l'Est.IsAny comme suit:
Je ne pense pas que vous auriez besoin d'initialiser toutes les valeurs, sur le formulaire type. Je devine votre DataFacade retourne un objet (ou d'une liste de dans ce cas)? Tout vous devez faire est de vous assurer que les objets retournés match les références de ceux qui sont retournés à partir de la DataFacade, vous n'avez pas besoin de s'inquiéter à propos des propriétés etc que vous n'êtes pas les tests de la construction de ces objets, simplement qu'ils sont retournés. Si j'ai mal compris et que vous êtes la construction d'objets dans la BusinessLogic alors c'est un problème différent. Personnellement, je n'aurais pas la logique d'entreprise dépend de la couche de données, mais c'est une autre discussion. 🙂
Vous le pouvez. Soit l'extrait à une méthode séparée ou, si elle est applicable à tous les tests de la classe, le mettre dans une méthode de configuration. Je ne suis pas familier avec XUnit, mais tous les autres framework de test, j'ai utilisé offre la possibilité de faire des courants d'installation donc je doute XUnit sera toute différente.
Et mon dernier commentaire, traiter votre code de test que vous traiteriez votre code de production, si cela semble un gâchis de faire des choses pour le rendre meilleur. Les Tests sont parfaits pour décrire le comportement d'un système, mais si elles sont difficiles à lire (et de maintenir), vous perdez beaucoup de valeur.
Modifier, s'avère que ce n'est pas mon dernier commentaire! Si vous êtes nouveau à l'ATS, dont je ne suis pas sûr de vous, ne tombez pas dans le piège de l'analyse de chaque et chaque classe dans votre application, c'est un modèle qui est devenu très répandu et il dévalue TDD, à mon avis. J'ai écrit un blog sur mes sentiments et Ian Cooper a donné un superbe présentation sur la question.
var expected = fixture.Create<int>();
devientvar expected = Any.Integer();
wrapper est un peu exagéré; alors que je suis sûr qu'il a sa place, il n'a pas d'adresse un tas de trucs que l'OP veut alors pourquoi introduire de la confusion de deux ensembles de syntaxe/convention.
généralement d'accord, mais dans certains cas, il m'a aidé à atteindre un peu plus clair code, peut-être un meilleur exemple en est, par exemple, Tout.IntegerOtherThan(42) qui n'a pas besoin d'elle, bien sûr - tout en suggérant quelques petites sucre syntaxique qui peut parfois être utile, merci
de l'AF me convient très bien. Une nouvelle lib commence avec -100 points en général.
A reçu le message, thx
OriginalL'auteur DoctorMick
Dans l'ensemble, l'origine du test semble bon. Il n'est pas possible ni facile à extraire le programme d'installation de Les talons et se moque de de l'épreuve, d'une façon générale.
Ce que vous peut faire, est de minimiser l'Arrangement de la phase de test. Voici l'origine du test de ré-écrite à l'aide de AutoFixture.Xunitpropres tests unitaires DSL:
La
TestConventions
attribut est défini comme:HTH
Types d'échantillon utilisé dans l'exemple:
OriginalL'auteur Nikos Baxevanis
Quelques notions de base:
Votre Classe de Test est instancié (et de son constructeur appelé) avant chaque Test est exécuté. par exemple, si votre classe de Test a trois méthodes [Fait] attribut, il est instanciée trois fois
Un TestFixture classe est une autre classe qui est censé être instanciée un seule fois pour tous les Tests dans votre classe de test.
Pour faire ce travail, votre classe de test doit mettre en œuvre les IUseFixture interface, par exemple, de mettre en œuvre un membre SetFixture()
Vous pouvez utiliser le même MyTestFixture classe pour plusieurs classes de Test.
À l'intérieur de la TestFixture vous faites tous de la Maquette Configurations.
Ici la présentation générale:
"À l'intérieur de la TestFixture vous faites la simulation de-Configurations - je suis en désaccord, vous ne devriez le faire toute l'installation qui est applicable à tous les tests de ce dispositif.
oui, bien sûr, dans le TestFixture vous faire (seulement) toutes les choses que vous avez besoin pour tous les tests
Pas aussi que xUnit v2 est beaucoup plus propre façon de gérer les appareils (par exemple, pas d'IUseFixture, juste ctor injection)
OriginalL'auteur DrKoch