Je conçois souvent le système où j'ai une classe dans mon système qui a un tas de méthodes protégées. Les méthodes protégées sont cela parce qu'elles devraient être accessibles aux spécialisations, et en tant que telles, je considère que les méthodes protégées sont un contrat entre ma classe générale et n'importe quelles classes spécialisées.Quel est le nom du motif?
donc je veux vérifier que ces méthodes se comportent correctement, donc mes tests unitaires auront besoin d'accéder aux méthodes protégées, ce qui est impossible dans C#, sauf en utilisant hacks sales comme réflexion.
La solution que je choisis normalement est que je crée une classe spécialisée dans mon test unitaire qui expose ces méthodes protégées comme publiques. Étant donné que je garde toujours les tests unitaires dans un ensemble distinct, le code système lui-même n'a pas accès à ces classes et, à l'intérieur de mon code système, la fonction protégée reste protégée.
// In the system code assembly
namespace MySystem {
public class SomeClass {
protected void DoSomething() {
...
}
}
}
// In the unit test assembly
namespace MySystem.Unittests {
public class SomeClass2 : SomeClass {
public new void DoSomething() {
base.DoSomething();
}
}
}
Mon test unitaire est maintenant en mesure de tester le comportement du membre protégé sur la classe parente par instancier la classe spécialisée. J'utilise aussi ceci encore plus loin pour pouvoir mocker les appels d'objet et de fonction fictive aux fonctions virtuelles protégées, mais ce code est un peu plus complexe, donc je vais juste le découper.
Je trouve cette façon d'accomplir cette tâche si simple que je ne peux pas être la seule personne à le faire, et donc je suppose qu'il doit y avoir une convention de nommage commune pour cela?
J'utilise simplement des interfaces et laisse les méthodes privées seules lors des tests. Ils ne devraient pas être beaucoup de toute façon si vous suivez le SRP. –
Je renommer SomeClass2 à TestableSomeClass. Cela clarifie le pourquoi et quoi. (Et, oui, nous utilisons beaucoup ce modèle ici ...) –
@Arjan - bien un point de ma question était de savoir quoi appeler SomClass2;) – Pete