Je me demande comment utiliser correctement NUnit. Tout d'abord, j'ai créé un projet de test distinct qui utilise mon projet principal comme référence. Mais dans ce cas, je ne suis pas en mesure de tester des méthodes privées. Je suppose que je dois inclure mon code de test dans mon code principal?! - Cela ne semble pas être la bonne façon de procéder. (Je n'aime pas l'idée du code d'expédition avec des tests.)
Comment testez-vous les méthodes privées avec NUnit?
c#
unit-testing
testing
nunit
MrFox
la source
la source
System.Reflection
vous permet d'accéder et d'appeler des méthodes non publiques en utilisant des indicateurs de liaison, vous pouvez donc pirater NUnit ou configurer votre propre framework. Ou (plus facile, je pense), vous pouvez configurer un indicateur de compilation (#if TESTING) pour changer les modificateurs d'accès, vous permettant d'utiliser les frameworks existants.Bien que je convienne que l'objectif des tests unitaires devrait être l'interface publique, vous obtenez une impression beaucoup plus granulaire de votre code si vous testez également des méthodes privées. Le cadre de test MS le permet grâce à l'utilisation de PrivateObject et PrivateType, ce n'est pas le cas de NUnit. Ce que je fais à la place, c'est:
De cette façon, vous n'avez pas à compromettre l'encapsulation en faveur de la testabilité. Gardez à l'esprit que vous devrez modifier vos BindingFlags si vous souhaitez tester des méthodes statiques privées. L'exemple ci-dessus est juste pour les méthodes d'instance.
la source
Un modèle courant pour écrire des tests unitaires consiste à tester uniquement les méthodes publiques.
Si vous trouvez que vous avez de nombreuses méthodes privées que vous souhaitez tester, c'est normalement un signe que vous devez refactoriser votre code.
Il serait erroné de rendre ces méthodes publiques sur la classe où elles vivent actuellement. Cela romprait le contrat que vous voulez que cette classe ait.
Il peut être correct de les déplacer vers une classe d'aide et de les rendre publics là-bas. Cette classe peut ne pas être exposée par votre API.
De cette façon, le code de test n'est jamais mélangé avec votre code public.
Un problème similaire est le test des classes privées ie. les classes que vous n'exportez pas de votre assemblage. Dans ce cas, vous pouvez explicitement faire de votre assemblage de code de test un ami de l'assemblage de code de production à l'aide de l'attribut InternalsVisibleTo.
la source
Il est possible de tester des méthodes privées en déclarant votre assembly de test en tant qu'assembly ami de l'assembly cible que vous testez. Voir le lien ci-dessous pour plus de détails:
http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx
Cela peut être utile car il sépare principalement votre code de test de votre code de production. Je n'ai jamais utilisé cette méthode moi-même car je n'en ai jamais trouvé le besoin. Je suppose que vous pouvez l'utiliser pour essayer de tester des cas de test extrêmes que vous ne pouvez tout simplement pas répliquer dans votre environnement de test pour voir comment votre code le gère.
Comme cela a été dit, vous ne devriez vraiment pas avoir besoin de tester des méthodes privées. Vous souhaitez plus que probablement refactoriser votre code en blocs de construction plus petits. Une astuce qui pourrait vous aider lorsque vous venez de refactoriser est d'essayer de réfléchir au domaine auquel votre système se rapporte et de penser aux objets «réels» qui habitent ce domaine. Vos objets / classes dans votre système doivent se rapporter directement à un objet réel qui vous permettra d'isoler le comportement exact que l'objet doit contenir et également de limiter les responsabilités des objets. Cela signifie que vous refactorisez logiquement plutôt que de simplement permettre de tester une méthode particulière; vous pourrez tester le comportement des objets.
Si vous ressentez toujours le besoin de tester en interne, vous pouvez également envisager de vous moquer de vos tests, car vous voudrez probablement vous concentrer sur un seul morceau de code. La moquerie est l'endroit où vous y injectez des dépendances d'objets, mais les objets injectés ne sont pas les objets «réels» ou de production. Ce sont des objets factices avec un comportement codé en dur pour faciliter l'isolement des erreurs de comportement. Rhino.Mocks est un framework de simulation gratuit populaire qui écrira essentiellement les objets pour vous. TypeMock.NET (un produit commercial avec une édition communautaire disponible) est un framework plus puissant qui peut simuler des objets CLR. Très utile pour se moquer des classes SqlConnection / SqlCommand et Datatable, par exemple lors du test d'une application de base de données.
Espérons que cette réponse vous donnera un peu plus d'informations pour vous informer sur les tests unitaires en général et vous aider à obtenir de meilleurs résultats avec les tests unitaires.
la source
Je suis en faveur de la capacité de tester des méthodes privées. Lorsque xUnit a démarré, il était destiné à tester les fonctionnalités après l'écriture du code. Le test de l'interface suffit à cet effet.
Les tests unitaires ont évolué vers un développement piloté par les tests. Avoir la capacité de tester toutes les méthodes est utile pour cette application.
la source
Cette question est dans ses années avancées, mais j'ai pensé partager ma façon de faire.
Fondamentalement, j'ai toutes mes classes de test unitaire dans l'assembly qu'ils testent dans un espace de noms 'UnitTest' sous le 'default' pour cet assembly - chaque fichier de test est enveloppé dans un:
block, et tout cela signifie que a) il n'est pas distribué dans une version et b) je peux utiliser les déclarations
internal
/Friend
level sans sauter de cerceau.L'autre chose que cela offre, plus pertinente pour cette question, est l'utilisation de
partial
classes, qui peuvent être utilisées pour créer un proxy pour tester des méthodes privées, donc par exemple pour tester quelque chose comme une méthode privée qui renvoie une valeur entière:dans les classes principales de l'assembly, et la classe de test:
De toute évidence, vous devez vous assurer de ne pas utiliser cette méthode pendant le développement, bien qu'une version Release indiquera bientôt un appel par inadvertance si vous le faites.
la source
L'objectif principal des tests unitaires est de tester les méthodes publiques d'une classe. Ces méthodes publiques utiliseront ces méthodes privées. Les tests unitaires testeront le comportement de ce qui est accessible au public.
la source
Toutes mes excuses si cela ne répond pas à la question, mais des solutions telles que l'utilisation de la réflexion, des déclarations #if #endif ou la mise en évidence de méthodes privées ne résolvent pas le problème. Il peut y avoir plusieurs raisons pour ne pas rendre les méthodes privées visibles ... et si c'est du code de production et que l'équipe écrit rétrospectivement des tests unitaires par exemple.
Pour le projet sur lequel je travaille, seul MSTest semble (malheureusement) avoir un moyen, en utilisant des accesseurs, de tester des méthodes privées.
la source
Vous ne testez pas les fonctions privées. Il existe des moyens d'utiliser la réflexion pour accéder aux méthodes et propriétés privées. Mais ce n'est pas vraiment facile et je déconseille fortement cette pratique.
Vous ne devriez tout simplement pas tester quoi que ce soit qui n'est pas public.
Si vous avez des méthodes et propriétés internes, vous devriez envisager de changer cela en public, ou d'expédier vos tests avec l'application (ce que je ne vois pas vraiment comme un problème).
Si votre client est capable d'exécuter une suite de tests et de voir que le code que vous avez livré "fonctionne", je ne vois pas cela comme un problème (tant que vous ne donnez pas votre adresse IP à travers cela). Les éléments que j'inclus dans chaque version sont des rapports de test et des rapports de couverture de code.
la source
En théorie des tests unitaires, seul le contrat doit être testé. c'est-à-dire uniquement les membres publics de la classe. Mais dans la pratique, le développeur souhaite généralement tester les membres internes. - et ce n'est pas mal. Oui, cela va à l'encontre de la théorie, mais en pratique, cela peut parfois être utile.
Donc, si vous voulez vraiment tester les membres internes, vous pouvez utiliser l'une de ces approches:
Exemple de code (pseudo code):
la source
Message: Method is not public
.Vous pouvez rendre vos méthodes protégées internes, puis les utiliser
assembly: InternalsVisibleTo("NAMESPACE")
dans votre espace de noms de test.Par conséquent, NON! Vous ne pouvez pas accéder aux méthodes privées, mais il s'agit d'une solution de contournement.
la source
Je rendrais le package de méthodes privées visible. De cette façon, vous le gardez raisonnablement privé tout en étant capable de tester ces méthodes. Je ne suis pas d'accord avec les gens qui disent que les interfaces publiques sont les seules qui devraient être testées. Il y a souvent du code vraiment critique dans les méthodes privées qui ne peuvent pas être correctement testées en passant uniquement par les interfaces externes.
Donc, cela revient vraiment à savoir si vous vous souciez davantage du code correct ou du masquage d'informations. Je dirais que la visibilité du package est un bon compromis car pour accéder à ces méthodes, quelqu'un devrait placer sa classe dans votre package. Cela devrait vraiment leur faire réfléchir à deux fois pour savoir si c'est une chose vraiment intelligente à faire.
Je suis un gars de Java, donc la visibilité du package pourrait être appelée quelque chose de complètement différent en C #. Autant dire que c'est lorsque deux classes doivent être dans le même espace de noms pour accéder à ces méthodes.
la source