2009-05-11 6 views
2

Je suis novice dans le domaine des tests unitaires, et j'aimerais savoir comment procéder pour tester une procédure (dans ce cas, une procédure qui «fait quelque chose» plutôt que «retourner») quelque chose ».Procédures de tests unitaires (par opposition aux fonctions)

Je sais que l'idée générale de tester une fonction qui renvoie une réponse est quelque chose comme

assert(yourfunction(sample, inputs) == expected_answer); 

mais me demande comment cela fonctionnerait si quelque chose ne retourne pas ou renvoie simplement un code d'état.

Répondre

2

Vous devez être en mesure de tester ce qu'il fait s. Par exemple, votre procédure ajoute-t-elle quelque chose à une collection? Définir une propriété? Créer un fichier?

Quoi qu'il en soit, on peut supposer que le changement est visible en quelque sorte. Vous avez juste besoin de travailler sur la façon de vérifier cet effet. Bien sûr, cela peut être plus facile à dire qu'à faire parfois, c'est pourquoi une approche fonctionnelle est plus facile à tester quand elle convient :) En particulier, les effets qui modifient les ressources externes (le système de fichiers, les bases de données etc) et les effets dépendent de les ressources externes (idem) sont plus difficiles à tester que celles qui ne changent que de manière assez «locale».

1

Dans certains cas, une procédure consiste à appeler des méthodes sur d'autres dépendances. Dans ce cas, si vous utilisez une approche par injection de dépendances, vous pouvez transmettre des failles de ces dépendances et utiliser des assertions ou des attentes pour vous assurer que les méthodes correctes sont appelées sur les dépendances, avec les paramètres corrects.

1

Pour les procédures, le «faire quelque chose» implique généralement des appels d'API ou d'autres manipulations d'objets.

Par exemple, une procédure peut écrire une ligne dans un fichier. Il utilise les appels API File I/O (ou un objet File IO) pour le faire "write a row".

Ce que vous voulez faire est de créer un objet "faux" pour représenter le fichier. L'objet Mock a juste assez de fonctionnalités pour collecter les résultats du test et les rendre visibles à une assertion. Ne pas écraser vos objets simulés, c'est un rat-trou du temps perdu.

En Python, nous faisons des choses comme ça.

class MockFile(object): 
    def __init__(self, aFileName, aMode): 
     self.name= aFileName 
     self.mode= aMode 
     self.buffer= None 
    def write(self, aRow): 
     self.buffer= str(aRow) 

Maintenant, nous pouvons fournir ce faux fichier à notre procédure au lieu d'un vrai fichier. Ans nous pouvons faire des assertions sur ce qui s'est passé.

class TestSomeProcedure(unittest.TestCase): 
    def testWrite(self): 
     mockFile= MockFile("name", "w") 
     theProcedureImTesting(args, args, args, mockFile) 
     self.assertEquals("The Row It Was Supposed to Write\n", mockFile.buffer) 
0

Il existe de nombreux cas:

Cas 1:

public class A 
    { 
     public void Foo() 
     { 
     Init(); 
     } 

     protected virtual void Init() 
     { 
     Do something; 
     } 
    } 

    [TestFixture] 
    public class ATests 
    { 
     [Test] 

     public void Foo_test() 
     { 
     A aStub = new A_Stub(); 
     aStub.Foo(); 
     Assert.IsTrue(aStub.wasInit); 
     } 

     public class A_Stub : A 
     { 
      public bool wasInit; 

      protected override void Init() 
      { 
      wasInit = true; 
      } 
     } 
    } 

Cas n ° 2: Lorsque votre méthode dépend d'un autre objet au lieu d'exécuter un membre appartenant à la même classe. Dans ce cas, je recommanderais d'utiliser un framework Mock. Personnellement, j'utilise Rhino.Mocks. Vous pouvez suivre ce lien pour voir Rhino.Mocks examples.