2017-09-19 4 views
1

Est-il nécessaire de tester 2 méthodes si elles utilisent seulement une méthode privée avec des arguments similaires?TDD, comment tester deux méthodes publiques si elles n'utilisent qu'une seule méthode privée sur rien d'autre?

Par exemple, j'ai une interface (contrat):

public interface IInterface 
{ 
    void Method1(arg1, arg2, arg3); 
    void Method2(arg1, arg2, arg3); 
} 

et la mise en œuvre de cette interface:

public class MyClass : IInterface 
{ 
    public void Method1(arg1, arg2, arg3) 
    { 
     Method3(arg1, arg2, arg3) 
    } 

    public void Method2(arg1, arg2, arg3) 
    { 
     Method3(arg1, arg2, arg3) 
    } 

    private void Method3(arg1, arg2, arg3) 
    { 
     // handle data 
    } 
} 

Par exemple, j'ai 3 tests pour Method1, est-il nécessaire de copier-coller ce test pour Method2 basé sur les règles TDD/RGB

+3

Vous devez tester les deux méthodes pour vous assurer que rien ne va pas ou pour déterminer ce qui ne va pas lorsque vous modifiez ces méthodes. Mais la première question à se poser est pourquoi une classe a deux méthodes avec le même corps. –

+0

@ChetanRanpariya Parce que j'ai l'interface, le contrat fort et dans d'autres implémentations d'interface nous avons 2 méthodes différentes. C'est un cas exceptionnel pour cette interface. –

+0

Oui ... Je m'en rends compte. Il est dans le meilleur intérêt de couvrir tout le code possible d'une classe via un test unitaire même s'il s'agit d'un doublon. Happy Coding ... –

Répondre

1

Il semble donc que vous ne voulez pas vraiment aller refactorisation les appelants de votre classe d'utiliser une interface simplifiée. Et cela pourrait être raisonnable si les lieux qui l'utilisent sont très répandus ou dans des bases de code partagées que vous ne pouvez pas refactoriser de manière bon gré mal gré.

Ce que je ferais serait de transformer cette classe en façade pour une interface plus propre. En d'autres termes, tirez votre méthode privée dans une nouvelle classe avec une interface concise. Utilisez ensuite la classe existante de la même manière que vous le faites déjà, mais avec une dépendance supplémentaire sur l'implémentation réelle.

Cela a deux avantages:

  1. Vous pouvez commencer à déplacer les classes qui dépendent de votre interface originale à la nouvelle mise en œuvre progressivement. (En particulier si vous désapprouvez ces méthodes pour alerter d'autres développeurs.) La façade peut être entièrement supprimée.
  2. Vous pouvez tester de manière approfondie votre nouvelle classe.
  3. Vous pouvez écrire deux tests unitaires très simples pour vérifier que vous appelez cette dépendance dans la classe existante. (Il n'est plus nécessaire de tester chaque cas.)
1

Est-il nécessaire de copier-coller ces tests pour la méthode 2 sur la base des règles TDD/RGB

Obligatoire est un peu trop fort; la police de TDD ne viendra pas frapper à votre porte.

Mais vous coloriez certainement en dehors des lignes. Si MyClass.Method2 est vraiment censé avoir le même comportement que MyClass.Method1 dans tous les cas intéressants, alors vous devriez avoir un test qui documente cette propriété.

Ce test n'a pas besoin d'être une pâte de copie des tests existants; ce pourrait être quelque chose comme un test axé sur les données.

[TestMethod()] 
public void testMethodEquivalence() { 
    val arg1 = TestContext.DataRow["arg1"] 
    val arg2 = TestContext.DataRow["arg2"] 
    val arg3 = TestContext.DataRow["arg3"] 

    MyClass expected = new MyClass(); 
    MyClass sut = new MyClass(); 

    Assume.That(sut, Is.EqualTo(expected)) 

    expected.Method1(arg1, arg2, arg3) 
    sut.Method2(arg1, arg2, arg3) 

    Assert.That(sut, Is.EqualTo(expected)) 
} 

Le point est qu'il devrait, quelque part, des contraintes assez sur la mise en œuvre de MyClass.Method2 qu'un codeur frais refactoring sans pitié sera alerté si des modifications du contrat de violer classe.

1

Le noyau point de tests unitaires est de vérifier contrat publique de votre code en cours de test.

En ce sens - la première observation serait: dans votre exemple, les deux méthodes prennent exactement les mêmes arguments et font exactement la même chose. Alors la réponse raisonnable serait: vous n'avez pas besoin Method1 et Method2 - vous rendrez Method3 public et appelez cela.

En supposant que votre exemple est une simplification, vous avez vraiment deux choix:

  • tester les méthodes publiques intensive
  • se concentrant sur Method1, et ayant quelques tests « ok, ça marche » pour Method2

il n'y a pas de règles d'or ici - vous devriez revenir en arrière et a décidé comment probablement il est par exemple que votre mise en œuvre wi changera jamais. Mais dans ce cas, vous feriez TDD, à droite. Cela signifie que si vous changez Method2, vous devrez commencer par vérifier les tests existants. Et quand vous puis trouver qu'ils ne suffisent pas - vous pouvez ajouter plus de choses.

En venant de là, je pencherais pour l'option 2.