2017-10-13 5 views
2

Dire que j'ai la classe suivante:Bonne pratique pour ajouter des méthodes protégées pour des tests unitaires?

public class ProblematicObject { 
    public static void methodToTest() { 
     SomeDependency dep = DependencyGetter.getDependency(SomeDependency.class); 
     dep.doStuff(); 
    } 
} 

Est-ce une pratique acceptable de modifier et ajouter des méthodes à cette classe pour le plaisir de faire plus propre de tests unitaires (aka éviter PowerMock)? Voici ce que la classe ci-dessus serait ressembler à:

public class ProblematicObject { 

    // new 
    private static SomeDependency dep; 

    // updated 
    public static void methodToTest() { 
     getSomeDependency().doStuff(); 
    } 

    // new 
    private SomeDependency getSomeDependency() { 
     if (this.dep == null) { 
      return DependencyGetter.getDependency(SomeDependency.class); 
     } 
     return dep; 
    } 

    // new, only used for testing, not in any impl code 
    @Deprecated 
    protected void setDependencyGetter(SomeDependency dep) { 
     this.dep = dep; 
    } 

} 

Je me souviens avoir lu quelque part que l'ajout de méthodes pour le bien des tests (au lieu de refactoring la classe problématique) est mal vu.

+0

Cochez cette question, il y a beaucoup d'opinions là-bas. [Comment est-ce que je teste une classe qui a des méthodes privées, des champs ou des classes internes?] (Https://stackoverflow.com/questions/34571/how-do-i-test-a-class-that-has-private-methods -fields-or-inner-classes). À mon avis, les méthodes privées devraient être testées via les méthodes publiques déjà disponibles. Ajouter des méthodes juste pour tester les mauvaises odeurs, et changer la visibilité pour les tests est une erreur potentielle en attente de se produire. –

+0

Personnellement, je pense que cela irait à l'encontre du but des tests unitaires de changer votre code spécifiquement pour les tests unitaires. L'idée des tests unitaires en général est de tester votre code dans le contexte pour lequel il devrait être utilisé. Je ne crois pas que chaque classe et chaque méthode est nécessaire pour avoir un cas de test unitaire. Je recommanderais de prendre du recul et d'examiner le contexte/flux de travail dans lequel ces méthodes/variables privées sont utilisées et éventuellement de créer un test d'unité fonctionnelle pour ce flux de travail. – Steve

+0

L'annotation '@ Deprecated' est une belle touche;) –

Répondre

1

Dans cet exemple particulier, vous améliorez la conception de votre classe en la rendant testable.

Ce nouveau test unitaire vous a fait réfléchir du point de vue du client ProblematicObject et vous a permis d'injecter cette dépendance.

+0

Mais parce que 'ProblematicObject' serait encore mieux changé pour obtenir le' SomeDependenc' via * constructor injection *. Et 'getDependency()' ne devrait pas être une méthode 'static' dans' DependencyGetter' ... –