Donc, je suis extrêmement nouveau dans les tests de logiciels et je cherche à ajouter quelques tests à l'une de mes applications. J'ai une méthode publique AddKeywords () qui le long de la route appelle une méthode privée refumetnvalidoperations (). Cette méthode privée appelle une API externe et compte ~ 50 lignes de code. Comme je le considère comme une méthode un peu complexe, je voudrais tester cela sans avoir à le faire en appelant la méthode AddOutword (). Pourtant, cela ne semble pas être possible (du moins pas si Junit). P>
Les informations que j'ai examinées suggèrent que le désir de tester ses méthodes privées pourrait être une odeur de code. Certaines personnes suggèrent que cela peut être un signe que cela devrait être refacturé dans une classe distincte et rendue publique. En outre, il existe les suggestions que si vous avez vraiment besoin de faire, vous pouvez faire des modifications à votre code de production par exemple. Changez la visibilité de la méthode privée. P>
Je ne vois pas vraiment pourquoi j'ai un problème avec ma conception de code actuelle, mais je n'aime pas non plus l'idée d'éditer mon code de production adapté à mes besoins de tests. P>
Comme je le dis - je suis plutôt nouveau à tester, alors toute aide est très appréciée. Aussi, s'il vous plaît laissez-moi savoir s'il ya plus d'informations supplémentaires, je peux fournir pour aider les réponses. P>
4 Réponses :
Si c'est Les tests d'unité sont censés être fonctionnalité orientés em>, pas code orienté em>. Vous testez des unités de fonctionnalité, pas des unités de code. P>
Quelle que soit la philosophie, une classe extérieure de votre implémentation ne peut pas accéder à la méthode privée sans pirater la JVM, donc vous n'avez pas de chance - vous devez soit modifier la visibilité de la méthode, faire un privé code>, il ne peut pas être considéré comme faisant partie de l'API de votre application, de sorte que c'est une odeur de code - lorsque le test se casse, est-ce correct ou non? P>
protégé code> Test API La classe de test de l'unité s'étend ou testez la fonction indirectement en appelant les méthodes publiques en l'utilisant. P>
Si vous ne voulez pas appeler addOutwords () code>, vous devriez peut-être simplement ajouter une autre méthode publique
testtremoveinvalidoperations () code>, qui appelle simplement le "code> privé" code> reflex () code>. Vous pouvez supprimer le test à une date ultérieure. P>
+1 pas une mauvaise idée. Changement mineur: faire des testremoveinvalidoperations () Accès par défaut (paquet) et ajoutez un commentaire pertinent pour clarifier son objectif est juste pour les tests d'unités.
-1 Il n'est jamais une bonne idée de piquer des trous dans votre code juste pour tester. Vous devez tester ce que vous avez, pas ce que vous voulez avoir. En outre, de bons tests ont tendance à exiger un bon design. Si le test veut que vous le refactorisez, c'est probablement raison. Et tester un morceau de code compliqué est plus que juste.
Certes, vous devez vous assurer de supprimer le code de test avant de libérer les fichiers au public. Quitter le code public est une mauvaise idée!
Je suggère de le refactoriser.
Les informations que j'ai examinées suggèrent que le désir de tester Les méthodes privées pourraient être une odeur de code. Certaines personnes suggèrent que C'est peut-être un signe que cela devrait être refacturé dans une classe distincte et rendu public. p> BlockQuote>
Vous avez couvert les diverses raisons et contre elle dans votre propre question, vous semblez être bien consciente des arguments. Mais vous avez une méthode qui semble plutôt compliquée et implique une API externe. cela vaut la peine d'être testé seul. em>
removeinvalidopérations () code> peut toujours être une méthode privée sur la classe dans laquelle il se trouve, mais il déléguerait essentiellement une autre dépendance. P >
xxx pré> Cela vous donne l'avantage supplémentaire de pouvoir remplacer cette dépendance à un moment donné, y compris de la possibilité de tester votre
AddOgewords () Code> Méthode sans placer réellement un Appel d'API externe, qui ferait tester cette méthode plus facile.
OperationRemover Code> pourrait être une interface, par exemple, et à des fins de test, vous passez simplement dans un talon à sa place au lieu de la version concrète utilisée dans la production. Quant à votre version de béton, vous pouvez écrire des tests indépendamment de ce qui se passe avec votre classe existante. P>
Je ne vois pas vraiment pourquoi j'ai un problème avec ma conception de code actuelle, mais aussi n'aime pas l'idée d'éditer mon code de production adapté à mon Tests des besoins. p> blockQuote>
La testabilité plus facile est un bénéfice secondaire. Regardez-y une autre façon: ce que vous faites réellement, c'est faire le code de manière lâche et extensible. Ci-dessus, nous avons séparé l'appel à l'API externe du code qui pourrait avoir besoin d'utiliser le résultat. L'API externe pourrait changer. Vous pourriez aller d'un service à un autre, mais le code qui utilise le résultat ne doit pas être pris en charge. Cette classe peut rester la même, seule la classe qui place réellement les appels doivent être modfiqués (ou remplacés). P>
Exemple de monde réel: L'année est de 2007 et vous travaillez pour une banque dans un grand centre financier aux États-Unis. Votre application doit utiliser des informations de compte. Votre code répond à un service Web d'une sorte de tri dans la banque et obtient les informations dont il a besoin, dans la forme dont elle a besoin, puis sur son traitement. En 2008, le secteur financier américain implose et votre banque (qui est sur le point de réduire l'effondrement) est gobillée par une autre banque. Votre demande est épargnée, sauf que vous devez maintenant contacter une API différente qui existe déjà dans la banque survivante pour obtenir des informations de compte à partir de là. Si le code qui consomme ces informations de compte doit changer? Pas nécessairement. C'est la même information de compte qu'auparavant, juste à partir d'une source différente. Non, tout ce qui doit changer est la mise en œuvre invoquant les API. Le code consommateur n'a jamais besoin de savoir. P>
Le fait qu'un tel couplage lâche favorise et facilite également les tests est un bonus. P> P>
Merci pour une réponse aussi détaillée! Cela m'a vraiment aidé à comprendre certains des avantages derrière une telle approche.
Habituellement, vous ne voudriez pas tester une méthode privée, mais il y a des exceptions. p>
Vous pourriez être tenté de tester une méthode privée si: p>
Vous n'avez pas pensé soigneusement sur la manière de tester la méthode privée indirectement en appelant les méthodes publiques existantes. p> li>
L'API de votre classe est trop inflexible. Les méthodes publiques ont besoin de plus Les paramètres, ou certaines des méthodes privées doivent être rendues publiques. p> li>
L'API de votre classe est assez flexible, mais sous le public méthodes qu'il a des méthodes privées assez compliquées en cours dessous. p> li> ol>
Basé sur votre question, vous pourriez être dans l'un de ces cas. p>
Pour (1), évidemment, vous devriez d'abord essayer de trouver un moyen de tester votre méthode privée avec les méthodes publiques existantes. p>
pour (2) et (3), les tests unitaires ne vous indiqueront pas ce que vous avez à faire. Ce que vous devez faire est d'écrire un exemple de code. Comme (3) est le cas où il est correct de tester des méthodes privées. Il y a divers astuces pour cela . Pour le code de production, ils valent mieux que l'exposition de votre méthode à l'utilisateur de l'API (le rendre public) pour que vous puissiez le tester. Ou scinder la fonctionnalité connexe en 2 classes pour que vous puissiez le tester. p>
au lieu de penser en termes de "odeurs de code", qui est imprécis et subjectif, vous pouvez penser en termes de Mais si vous pensez vraiment qu'il est important de tester votre méthode privée, et si vous ne pouvez pas le faire correctement via les méthodes publiques, ne sacrifiez pas la correction de votre code! Testez la méthode privée. Le pire des cas est votre code de test est Messier et vous devez réécrire les tests lorsque la méthode privée change. p>
Une solution rapide que j'ai souvent utilisée consiste à modifier l'accès de Private à Parfait (Package) et de commentaire
// Accès au paquet pour les tests d'unités uniquement. Code> Si cela est acceptable dépend de vos normes de codage et de la quantité Vous faites confiance à vos collègues programmeurs pour comprendre que cette méthode, même si l'accès au paquet n'est pas une "réelle API".