11
votes

Que faire quand Java Meilleure pratiques en conflit avec Mockito

Mon équipe de développement a commencé à utiliser Mockito et avoir des cours qui ont été définis comme «final». J'ai lu en efficace Java par Joshua Bloch et dans le thread quand utiliser final que Toutes les classes doivent utiliser le modificateur final. Il y a eu un désaccord dans le fil, mais je suis d'accord avec l'idée de forcer la composition de classe sauf si l'héritage n'a de sens.

Que dois-je faire lorsque je veux tester des cours à l'aide d'un cadre de test comme Mockito qui nécessite des classes pour ne pas avoir le "final" modificateur? J'espère que quelqu'un d'autre a rencontré des problèmes similaires au cours de leur développement. Quelles résolutions votre équipe de développement arriva-t-elle?

Il y a deux réponses évidentes telles que l'utilisation de JMock ou supprimer le modificateur "final" sur les classes que nous voulons tester, mais nous voulons coller avec un cadre de test externe (à part Junit) et il peut être difficile de convaincre d'autres développeurs. Pour supprimer le modificateur «final».

merci.


1 commentaires

Faire toutes les classes finale n'est certainement pas une meilleure pratique ... Cela fait longtemps que la lecture de Java efficace, mais le consensus du fil lié ne semble certainement pas implique que non plus. Vous devriez marquer des classes finale pour signifier une raison pour laquelle ils ne devraient pas être prolongés - s'il n'y a aucune raison, il ajoute simplement une complexité inutile - comme vous l'avez trouvé. De plus, si vous vous rendez compte que vous avez besoin d'étendre la classe quelque part sur la route, vous devez modifier le code de la classe d'origine pour écrire la nouvelle classe - violer le principe ouvert / fermé.


3 Réponses :


10
votes

De quoi avez-vous le plus besoin:

  1. la possibilité de s'assurer que quelqu'un n'hérite pas de votre classe ou
  2. La possibilité de vous assurer que votre code est testable à l'aide de votre cadre de choix moqueur?

    Généralement, je pense que vous n'avez pas besoin d'appliquer (1). Pour moi, la testabilité (2) est beaucoup plus importante. Qu'est-ce qui convient au mieux à votre situation?


2 commentaires

La testabilité est beaucoup plus importante dans l'IMHO et je crois que cela correspond à notre situation.


Il n'est pas nécessaire de sacrifier la conception pour des raisons de "testabilité". Vous pouvez avoir les deux, en utilisant simplement le bon outil pour le travail. Dans ce cas, utilisez l'un des outils moqueurs Java pouvant se moquer de méthodes et de classes finales: JMockit (mon propre outil) ou PowerMock (qui prend en charge l'API Mockito, vous n'avez donc pas à réécrire complètement les tests existants).



4
votes

Si vous voulez que vos classes soient finales, vous pouvez leur avoir des interfaces. Les interfaces sont moquables.


0 commentaires

4
votes

Comme déjà mentionné dans l'autre réponse, vous pouvez rendre vos classes finales à mettre en œuvre Interface (s) et dans vos tests se moquent de l'interface (s).

C'est l'un des avantages de l'utilisation d'objets simulés; Dans des scénarios comme celui-ci, ils vous font penser à la manière dont le code peut être mieux organisé. Si votre base de code a beaucoup de référence aux classes finales (contraignant ainsi à la mise en œuvre du béton), il viole le principe de OO de «programmation à une interface» et la nécessité d'une meilleure vérification vous aiderait à référer à l'élimination de la dépendance sur les implémentations concrètes.

Ce document sur l'utilisation d'objets simulés Endo-Test: Test de l'unité avec des objets simulés a Une section (4.4) intitulée Discovery interface qui explique comment des objets simulés aident à la découverte des interfaces.


2 commentaires

J'aime l'idée de la découverte d'interface.


Lorsque j'écris du code qui utilise une classe finale et que cette classe ne met pas en œuvre une interface distincte, je suis pas violer le "programme à une interface, pas une mise en œuvre" GOF Principe. Le principe fait pas exige que chaque classe implémente une interface distincte. D'autres parties du livre GOF rendent cela clair, pour ceux qui sont disposés à le lire réellement.