Comment pouvez-vous tester les méthodes privées avec NUnit?
Je me demande comment l'utiliser NUnit correctement. J'ai d'abord créé un Test-Projet qui utilise mon principal projet en tant que référence. Mais dans ce cas, je ne suis pas en mesure de tester des méthodes privées. Ma conjecture est que j'ai besoin de mes testcode dans mon code principal?! - Qui ne semble pas être la bonne façon de le faire. (Je n'aime pas l'idée de l'expédition de code avec des tests en elle.)
Comment pouvez-vous tester les méthodes privées avec NUnit?
Vous devez vous connecter pour publier un commentaire.
Généralement, les tests unitaires adresse à une classe de l'interface publique, sur la théorie que de la mise en œuvre est négligeable tant que les résultats sont corrects du point de vue des clients.
Donc, NUnit ne fournit pas de mécanisme pour le test de non-membres du public.
System.Reflection
vous permet d'accéder et d'invoquer la non-public des méthodes à l'aide de la liaison de drapeaux, de sorte que vous pourrait pirater NUnit ou mettre en place votre propre cadre de référence. Ou (plus facile, je pense), vous pourriez mettre en place au moment de la compilation du pavillon (#si le TEST) pour modifier les modificateurs d'accès, vous permettant d'utiliser les cadres existants.Alors que je suis d'accord que l'objet de tests unitaires doivent être l'interface publique, vous obtenez un beaucoup plus granulaire impression de votre code si vous testez les méthodes privées ainsi. Le MS framework de test permet grâce à l'utilisation de PrivateObject et PrivateType, NUnit ne le fait pas. Ce que je faire à la place est:
De cette façon, vous n'avez pas à compromettre l'encapsulation en faveur de la testabilité. Gardez à l'esprit que vous aurez besoin de modifier votre BindingFlags si vous voulez tester privé méthodes statiques. L'exemple ci-dessus est seulement pour les méthodes d'instance.
Un modèle commun pour l'écriture de tests unitaires est de tester les méthodes publiques.
Si vous trouvez que vous avez beaucoup de méthodes privées que vous souhaitez tester, normalement, c'est un signe que vous devez restructurer le code.
Il serait erroné de faire de ces méthodes publiques de la classe où ils vivent actuellement.
Qui permettrait de rompre le contrat que vous souhaitez que cette catégorie à avoir.
Il peut être approprié de les déplacer vers une classe d'assistance et de les rendre public.
Cette classe ne peut pas être exposés par votre API.
De cette façon, le code de test est jamais mélangé avec votre code public.
Un problème similaire est mise à l'essai des cours privés d'ie. les classes que vous ne l'exportation à partir de votre assemblée.
Dans ce cas, vous pouvez explicitement faire votre test du code de l'assemblée un ami de la production de code de l'assemblée à l'aide de l'attribut InternalsVisibleTo.
Il est possible de tester les méthodes privées en déclarant votre test de montage comme un ami de l'assemblée de la cible de l'assemblée 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 comme il le fait pour la plupart séparer votre code de test à partir de votre code de production. Je n'ai jamais utilisé cette méthode à moi-même que je n'ai jamais trouvé un besoin pour elle. Je suppose que vous pourriez l'utiliser pour essayer et tester extrême des cas de test qui vous simplement ne pouvez pas reproduire dans votre environnement de test pour voir comment votre code gère.
Comme il a été dit, cependant, que vous ne devriez vraiment pas besoin de tester des méthodes privées. Vous plus que probable souhaitez restructurer le code en petits blocs de construction. Une astuce qui pourrait vous aider quand vous venez à refactoriser est à essayer et à réfléchir sur le domaine que votre système se rapporte à et à réfléchir sur le "réel", les objets qui peuplent ce domaine. Vos objets/classes dans votre système devrait se rapporter directement à un objet réel qui vous permettra d'isoler le comportement exact que l'objet doit contenir et de limiter les objets de responsabilités. Cela signifie que vous êtes refactoring logiquement plutôt que juste pour le rendre possible de tester une méthode particulière, vous serez en mesure de tester le comportement des objets.
Si vous vous sentez toujours le besoin de test interne, alors vous pourriez aussi envisager de moqueur dans vos tests que vous êtes susceptibles de vouloir se concentrer sur un morceau de code. Se moquant est l'endroit où vous injecter un des objets de la dépendance à elle, mais les objets injectés ne sont pas des "vrais" ou de la production des objets. Ils sont factices objets avec codé en dur comportement pour le rendre plus facile à isoler le comportement des erreurs. Rhino.On se moque de est un populaire gratuit moqueur cadre qui sera, pour l'essentiel écrire les objets pour vous. TypeMock.NET (un produit commercial avec un community edition) est l'un des plus puissants cadre qui peut se moquer des objets CLR. Très utile pour se moquer de la SqlConnection/SqlCommand et Datatable classes par exemple lors de l'essai d'une base de données d'application.
J'espère que cette réponse vous donnera un peu plus d'informations pour vous informer sur les Tests Unitaires en général et de vous aider à obtenir de meilleurs résultats de Tests Unitaires.
Je suis en faveur d'avoir la capacité de tester des méthodes privées. Lorsque xUnit commencé il a été conçu pour tester la fonctionnalité après le code a été écrit. Test de l'interface est suffisant pour cela.
Tests unitaires a évolué vers le développement piloté par les tests. Avoir la capacité de tester toutes les méthodes utiles pour l'application.
L'objectif principal de l'unité de test est de tester les méthodes publiques de la classe. Ces méthodes publiques pour utiliser ces méthodes privées. Unité de test permettra de tester le comportement de ce qui est publiquement disponible.
À cette question est dans son âge avancé, mais j'ai pensé que je devais partager ma manière de faire.
En gros, j'ai tous mes test de l'unité de classes dans l'assemblée, ils ont testé dans un "UnitTest' espace de noms en-dessous de la valeur "par défaut" pour que l'assemblée, à chaque fichier de test est enveloppé dans un:
bloc, et tout cela signifie que a) il n'est pas distribué dans un communiqué et b) je peux utiliser
internal
/Friend
niveau des déclarations sans cerceau de sauter.Autre chose de cette offre, la plus pertinente à cette question est, est l'utilisation de
partial
classes, qui peuvent être utilisés pour créer un proxy pour tester les méthodes privées, afin par exemple de tester quelque chose comme une méthode qui retourne une valeur de type entier:dans les principales classes de l'assemblée, et la classe de test:
Évidemment, vous devez vous assurer que vous n'utilisez pas cette méthode, tout en développant, si un Communiqué de construire sera bientôt indiquer une inadvertance de l'appel à elle si vous n'.
Excuses si cela ne répond pas à la question, mais des solutions telles que l'utilisation de la réflexion, #si #endif déclarations ou privée méthodes visible ne permet pas de résoudre le problème. Il peut y avoir plusieurs raisons pour ne pas faire l'méthodes privées visible que... si c'est le code de production et l'équipe est rétrospectivement l'écriture de tests unitaires, par exemple.
Pour le projet que je suis en train de seulement MSTest (malheureusement) semble avoir un sens, de l'utilisation des accesseurs, à l'unité de test des méthodes privées.
Vous n'avez pas fait de test des fonctions privées.
Il existe des moyens pour utiliser la réflexion pour entrer dans les méthodes et propriétés privées. Mais ce n'est pas vraiment facile, et je déconseille vivement cette pratique.
Vous simplement ne devrait pas tester tout ce qui n'est pas public.
Si vous avez des méthodes et des propriétés, vous devriez envisager de changer de public, ou de la livraison de vos tests avec l'application (chose que je n'ai pas vraiment le voir comme un problème).
Si votre client est en mesure d'exécuter une Suite de tests et de voir que le code que vous avez livrés est en fait le "travail", je ne vois pas cela comme un problème (tant que vous ne donnez pas votre adresse IP à travers ce). Des choses que je inclure dans chaque version sont les comptes rendus des tests et des rapports de couverture de code.
Vous pouvez faire vos méthodes protégées interne, puis à l'aide de
assembly: InternalVisibleTo("NAMESPACE")
pour vos tests d'espace de noms.
Donc, NON! Vous ne pouvez pas accéder méthodes privées, mais c'est un travail autour de.
Dans la théorie de l'Unité de Test uniquement sur le contrat devrait être testé. c'est à dire uniquement les membres publics de la classe. Mais, dans la pratique, le développeur veut habituellement de test interne des membres. - et il n'est pas mauvais. Oui, il va à l'encontre de la théorie, mais en pratique, il peut parfois être utile.
Donc, si vous voulez vraiment tester les membres internes, vous pouvez utiliser l'une de ces approches:
approche simple
assebly
à partir de votre objet d'essais de classe.
Exemple de Code (pseudo-code):
Message: Method is not public
.Je ferais les méthodes privées paquet visible. De cette façon, vous faire 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 doivent être testés. Il est souvent très critique de code dans les méthodes privées qui ne peuvent pas être correctement testés par seulement en passant par les interfaces externes.
Donc vraiment résume à si vous vous souciez plus le code est correct ou se cacher de l'information. Je dirais package de visibilité est un bon compromis car, pour pouvoir accéder à ces méthode que quelqu'un aurait de la place de leur catégorie dans votre colis. Qui devrait vraiment faire réfléchir à deux fois quant à savoir si c'est vraiment une chose intelligente à faire.
Je suis un Java guy btw, sorte de package visiblilty pourrait être appelé quelque chose d'entièrement différent en C#. Il suffit de dire que c'est lorsque les deux classes doivent être dans le même espace de noms pour accéder à ces méthodes.