En utilisant une classe ami par rapport à l'ajout d'accesseurs pour les tests unitaires en C ++?

StackOverflow https://stackoverflow.com/questions/1149244

  •  18-09-2019
  •  | 
  •  

Question

Est-il préférable d'ajouter des fonctions qui retournent l'état interne d'un objet pour les tests unitaires, plutôt que de faire la classe d'essai d'un ami? -. En particulier, quand il n'y a pas d'utilisation pour les fonctions, sauf dans le cas des tests unitaires

Était-ce utile?

La solution

Les tests unitaires devraient 95% du temps d'essai que la surface exposée publiquement d'une classe. Si vous testez quelque chose sous les couvertures, qui teste les détails de mise en œuvre, ce qui est par nature fragile, parce que vous devriez être en mesure de changer facilement la mise en œuvre et ont encore le travail des tests. Non seulement il est fragile, mais vous pouvez aussi être tenté dans les choses de tests qui ne sont pas réellement possible dans les scénarios d'utilisation prévus, ce qui est une perte de temps.

Si le point des accesseurs que vous voulez ajouter est juste pour vérifier si la fonction avait l'effet désiré, la conception de votre classe peut transgresser un autre principe qui est que devrait toujours faire une classe comme l'état de la machine clairement quel état son dans, si cela affecte ce qui se passe quand les gens interagissent avec la classe. Dans ce cas, il serait bon de fournir les accesseurs en lecture seule. Si elle ne modifie pas le comportement de la classe, se référer à mon bit précédent sur les détails de mise en œuvre.

Et comme vous l'avez dit à juste titre, encombrent la surface publique d'une classe avec des choses non utilisés est également indésirable pour ses propres raisons.

Si I HAD pour ramasser entre accesseurs et friending dans votre cas, je choisirais friending, tout simplement parce que et votre test possèdent peut changer dans un pincement. Vous pouvez ne pas posséder le code par le clown qui trouve un moyen d'utiliser vos accesseurs supplémentaires, et vous serez coincé.

Autres conseils

Je suis en désaccord avec la réponse acceptée et recommande plutôt l'utilisation d'une classe d'ami.

Une partie de l'état que vous testez est probablement spécifique à la mise en œuvre de votre classe; vous testez les détails que tout autre code ne connaît normalement pas ou se soucient et ne doit pas se fier. accesseurs publiques font ces détails de mise en œuvre une partie de l'interface de la classe. Si l'état interne que vous testez ne fait pas partie de l'interface destinée, il ne doit pas être visible par les fonctions publiques. D'un point de vue puriste que vous êtes coincé entre deux mauvaises réponses, comme les classes d'ami sont également techniquement partie de l'interface publique. Dans mon esprit, la question devient, quelle option est moins susceptible de conduire à un mauvais choix de codage sur la route? Voulez-vous profiter d'un ensemble de fonctions accesseurs publique dépendant de la mise en œuvre sera inadvertantly favoriser un modèle conceptuel dépendant de la mise en œuvre de la classe, ce qui conduit à une utilisation en fonction de la mise en œuvre de la classe. Une seule classe d'ami, bien nommé et documenté, est moins susceptible d'être abusé.

Alors qu'en général, je suis entièrement d'accord avec la recommandation de préférer les fonctions accesseurs sur un accès direct aux variables membres, je ne suis pas d'accord que cette meilleure pratique applique aux tests unitaires d'état interne en fonction de la mise en œuvre. Un terrain d'entente raisonnable est d'utiliser private accesseurs à ces morceaux de l'état de votre test unitaire se soucieront, et être assez disciplinés pour utiliser les fonctions accesseurs dans vos tests unitaires. Juste mon avis.

Utilisation des classes d'ami pour les tests unitaires est un tout à fait légitime et vous permet de maintenir l'encapsulation. Vous ne devez pas modifier votre interface publique des classes simplement pour rendre la classe plus testable. Pensez-y de cette façon. Que faire si vous avez acheté un tiers bibliothèque FTP et que vous essayez de l'utiliser et il est l'interface publique est encombré avec un tas de méthodes que vous ne même pas besoin de savoir sur tout simplement parce que des tests unitaires! Même la modification d'une interface protégée pour compenser les tests unitaires est BAD. Si je suis une héritant de la classe, je ne veux pas avoir à se soucier de ce que les méthodes sont utiles pour moi et ceux qui ne sont là que des tests unitaires !!! Utilisation des classes d'amis pour les tests unitaires vous aide à maintenir un simple, plus facile à utiliser l'interface de classe; il contribue à préserver l'encapsulation et de l'abstraction !!!

Je l'ai entendu l'argument selon lequel l'utilisation des classes d'ami pour les tests unitaires est mauvais parce que la classe en cours de test ne doit pas être « étroitement couplé » avec sa classe de test et il ne devrait pas « savoir » quoi que ce soit au sujet de sa classe de test. Je n'achète pas. Il est une seule ligne ajoutée au sommet de la classe:

classe ami MyClassTest;

et maintenant vous pouvez tester votre classe comme vous le souhaitez!

Maintenant, je suis d'accord que vous ne devriez pas utiliser une classe ami à moins qu'il est nécessaire. Si vous pouvez tester ce test a besoin sans en faire un ami, par tous les moyens faire. Mais si la vie devient difficile et en utilisant une classe ami rend la vie plus facile, l'utiliser!

Je recommande d'utiliser accesseurs plutôt que de permettre l'accès par des membres du public ou des classes d'amis.

Je ne pense pas que l'utilisation de la classe d'ami vous obtient réellement des avantages, et il a le potentiel de rendre votre vie bien pire sur la route. Si votre code va rester autour depuis longtemps, il y a une bonne chance qu'il pourrait être utilisé de manière que vous ne prévoyez pas. Les fonctions d'accès peuvent être utilisés que pour les tests maintenant, mais qui sait ce qui se passera à l'avenir? Utilisation des accesseurs plutôt que de fournir un accès direct aux variables vous donne beaucoup plus de flexibilité, et il a un coût très faible.

L'autre argument est que l'utilisation accesseurs plutôt que des membres du public est une bonne habitude. Développer de bonnes habitudes est une compétence importante en tant que programmeur.

Comment de faire état interne « protégé »? Et puis faire unittest en utilisant la classe dérivée.

Je pense qu'il doit y avoir une distinction entre l'avenir épreuvage la classe en fournissant des accesseurs à ses utilisateurs s'il est logique de le faire, et l'amélioration de la testabilité. Je suis pas non plus un grand fan de lier d'amitié avec des classes dans le seul but de l'essai, car cela introduit un couplage étroit dans un endroit où je préfère ne pas l'avoir.

Si l'usage exclusif des accesseurs est de fournir un moyen pour les cas de test pour vérifier l'état interne de la classe, il n'a normalement pas de sens de les exposer publiquement. Il peut également attacher les détails de mise en œuvre que vous voudrez peut-être changer plus tard, mais vous pouvez trouver pas parce que quelqu'un d'autre utilise ledit accesseurs.

Ma solution préférée pour ce serait de fournir protégés accesseurs de communiquer clairement aux utilisateurs de la classe que ceux-ci ne font pas partie de l'interface publique. Vos essais seraient alors créer une classe dérivée minimale de l'original qui contient des talons d'appel-through pour les fonctions du parent, mais rend aussi les accesseurs publics afin que vous puissiez les utiliser dans les cas de test.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top