2008-10-21 5 views
1

Dans ma question As a “mockist” TDD practitioner, should I mock other methods in the same class as the method under test?, Avdi répondu "Personnellement, je pense que se moquer de soi-même est presque toujours une odeur de code, c'est tester l'implémentation plutôt que le comportement." Il a peut-être raison, mais souvent je ne peux pas distinguer entre la mise en œuvre et le comportement.Comment éviter le code dupliqué dans mes tests et éviter de me moquer de moi-même?

J'ai un autre exemple (en pseudo-code de style Python) qui peut conduire à des réponses utiles:

class Consumer: 

    def spec_dirpath: 
     client = VCS.get_connection(self.vcs_client_name) 
     client.sync() 
     return client.dirpath() 

    def spec_filepath: 
     filepath = os.path.join(spec_dirpath(), self.spec_filename) 
     if not os.path.exists(filepath): 
      raise ConsumerException 
     return filepath 

    def get_components: 
     return Components.get_components_from_spec_file(self.spec_filepath()) 

L'idée ici est que la méthode get_components appelle la méthode spec_filepath afin d'obtenir un chemin vers un fichier que la méthode de classe get_components_from_spec_file va lire une liste de composants. La méthode spec_filepath appelle à son tour spec_dirpath, qui synchronise le répertoire contenant le fichier spec du système VCS et renvoie le chemin d'accès à ce répertoire. (Essayez de ne pas chercher des bugs dans ce code - c'est pseudo-code, après tout.)

Je cherche des conseils sur la façon de tester ces méthodes ...

Test spec_dirpath devrait être assez simple . Je peux mocker la classe VCS et lui faire retourner un objet mock et confirmer que les méthodes appropriées sont appelées (et que la méthode spec_dirpath retourne ce que la méthode dirpath de mock renvoie).

Mais si je ne me moque pas de spec_dirpath lors du test de spec_filepath, comment éviter de dupliquer le même code de test du code spec_dirpath dans le test spec_filepath? Et si je ne me moque pas de spec_filepath lors du test de get_components, comment éviter de dupliquer le code de test depuis spec_filepath et spec_dirpath?

Répondre

1

Les tests unitaires fonctionnent mieux avec une forme d'injection de dépendance. Dans ce cas, parce que vous créez le client dans le code, vous créez une dépendance dans votre test qui nécessite une forme de simulation dynamique à gérer. (Nous utiliserions un simulacre partiel dans ce cas pour simuler nos appels qui créent des dépendances pour éviter d'avoir à tester ces dépendances aussi).

Si vous injectez la dépendance au démarrage (c'est-à-dire que vous passez dans un objet client), vous pouvez facilement le simuler et ne pas avoir de difficultés majeures à tester uniquement la classe.

Vous avez donc besoin d'une solution partielle ou d'une solution d'injection de dépendances pour atteindre ces objectifs.

1

Habituellement, dans les tests unitaires, le comportement se réfère à un comportement observable de l'extérieur. En utilisant votre exemple, le comportement observable serait la liste des composants que vous obtenez de get. Le fait qu'ils proviennent d'un fichier est l'implémentation, donc je conseillerais de construire vos tests autour de la liste des composants que vous récupérez sans se moquer de la récupération de fichiers car elle est interne à la classe, avec un code d'installation pour fournir un fichier approprié.

L'alternative serait de rendre le fichier dont les composants ont été chargés à partir d'une dépendance pour la classe, par ex. en faire un paramètre constructeur ou un paramètre de méthode, pour permettre au fichier d'être spécifié en externe à la classe. Dans ce cas, il serait externe et donc je me moquerais de lui pour s'assurer que vous obteniez un comportement cohérent de celui-ci pour vous assurer que votre classe l'utilisait correctement.

Questions connexes