La compilation conditionnelle est-elle une stratégie de maquette / stub valide pour les tests unitaires?

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

Question

Dans une question récente sur le stubbing, de nombreuses réponses ont suggéré des interfaces C # ou des délégués pour la mise en œuvre des stubs, mais une réponse suggérée à l'aide de la compilation conditionnelle, en conservant la liaison statique dans le code de production. Cette réponse a été moddée -2 au moment de la lecture, donc au moins 2 personnes ont vraiment pensé que c'était une mauvaise réponse. Peut-être que la mauvaise utilisation de DEBUG en était la raison, ou peut-être l’utilisation de la valeur fixe au lieu d’une validation plus poussée. Mais je ne peux pas m'empêcher de me demander:

L'utilisation de la compilation conditionnelle est-elle une technique inappropriée pour mettre en œuvre des stubs de test unitaire? Parfois? Toujours?

Merci.

Modifier-ajouter: je voudrais ajouter un exemple d'expérience expérimentale:

class Foo {
    public Foo() { .. }
    private DateTime Now { 
      get {
#if UNITTEST_Foo
        return Stub_DateTime.Now;
#else
        return DateTime.Now;
#endif
      }
    }
    // .. rest of Foo members
}

en comparant à

interface IDateTimeStrategy { 
    DateTime Now { get; }
}
class ProductionDateTimeStrategy : IDateTimeStrategy {
  public DateTime Now { get { return DateTime.Now; } }
}
class Foo {
    public Foo() : Foo(new ProductionDateTimeStrategy()) {}
    public Foo(IDateTimeStrategy s) { datetimeStrategy = s; .. }
    private IDateTime_Strategy datetimeStrategy;
    private DateTime Now { get { return datetimeStrategy.Now; } }
}

Ce qui autorise la dépendance sortante sur " DateTime.Now " être écrasé via une interface C #. Cependant, nous avons maintenant ajouté un appel de dispatch dynamique où statique suffirait, l'objet est plus volumineux, même dans la version de production, et nous avons ajouté un nouveau chemin d'échec pour le constructeur de Foo (l'allocation peut échouer).

Suis-je inquiet pour rien ici? Merci pour les commentaires jusqu'à présent!

Était-ce utile?

La solution

Essayez de garder le code de production séparé du code de test. Maintenir différentes hiérarchies de dossiers .. différentes solutions / projets.

Sauf ... vous êtes dans le monde du code C ++ hérité. Ici, tout est permis. Si des blocs conditionnels vous aident à obtenir une partie du code testable et que vous voyez un avantage. Faites-le. Mais essayez de ne pas le laisser devenir plus compliqué que l'état initial. Commentez clairement et démarquez les blocs conditionnels. Procéder avec prudence. C’est une technique valable pour obtenir du code hérité sous un harnais de test.

Autres conseils

Je pense que cela réduit la clarté pour les personnes qui révisent le code. Vous ne devriez pas avoir à vous rappeler qu'il existe une balise conditionnelle autour d'un code spécifique pour comprendre le contexte.

Non, c'est terrible. Il fuit le test dans votre code de production (même s’il est conditionné)

Mauvais Mauvais.

Le code de test doit être évident et non mélangé dans les mêmes blocs que le code testé.

C’est à peu près la même raison pour laquelle vous ne devriez pas écrire

if (globals.isTest)

J'ai pensé à une autre raison pour laquelle c'était terrible:

Souvent, vous simulez ou stubez quelque chose, vous voulez que ses méthodes renvoient des résultats différents en fonction de ce que vous testez. Cela l’empêche ou le rend maladroit, comme si de rien n'était.

Il peut s’avérer utile en tant qu’outil sur lequel vous pouvez vous pencher pour modifier la testabilité dans une base de code volumineuse. Je peux voir comment vous pourriez utiliser de telles techniques pour permettre des changements plus modestes et éviter un "big bang". refactoring. Cependant, je m'inquiéterais de trop m'appuyer sur une telle technique et essayerais de faire en sorte que de telles astuces ne survivent pas trop longtemps dans la base de code, sinon vous risqueriez de rendre le code d'application très complexe et difficile à suivre.

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