2010-12-09 34 views
4

Plus je lis par exemple la maquette, plus je confus ...Comment écrire un test unitaire en utilisant un objet simulé?

J'ai méthode CLASSA manger() qui appelle FatDude classe eatThemAll()

public class classA { 

    FatDude dude = new FatDude(); 

    public String eat() { 
     String result = dude.eatThemAll(); 
    } 
} 

public class FatDude { 
    public String eatThemAll() { 
     return "never full"; 
    } 
} 

Maintenant, je veux tester CLASSA manger () en se moquant de la classe FatDude.

public class MockFatDude extends FatDude { 
    //override 
    public String eatThemAll() { 
     return "very full"; 
    } 
} 
------------- test -------------- 
public class DoTest { 

    public void runTest() { 
     classA cl = new ClassA(); 
     String out = cl.eat(); 
     assertEqual(out, "very full"); 
    } 
} 

Cette requêteTestTest() n'utilisera pas bien sûr la classe MockFatDude. Une façon je peux penser est de changer le code pour passer méthode FatDude à manger() de ClassA comme:

public class classA { 

     public String eat(FatDude dude) { 
      String result = dude.eatThemAll(); 
     } 
    } 

changer ensuite ma méthode de test:

public class DoTest { 

     public void runTest() { 
      classA cl = new ClassA(); 
      String out = cl.eat(new MockFatDude()); 
      assertEqual(out, "very full"); 
     } 
    } 

Mais comme vous pouvez le voir, je a dû changer le code source pour répondre à mes besoins. Est-ce la bonne façon de faire? Que faire si je ne suis pas autorisé à changer mon code source? Je sais si j'applique le concept TDD, il est OK de changer le code source mais j'aimerais entendre un avis ou un conseil si ce que j'ai montré ci-dessus est la bonne façon de faire.

+0

Est-ce java ou C#? Quels outils utilisez-vous? S'il vous plaît, ajoutez des tags appropriés. Je vous remercie. –

+1

@maksymko: Je ne pense pas que le langage ou les outils soient importants pour cette question, à part le fait que c'est un langage orienté objet. –

+0

@calavera: je voulais juste le clarifier pour une catégorisation/filtrage plus approprié, et non comme un moyen d'aider à répondre à la question. –

Répondre

4

Mocking et le Dependency Inversion Principle (DIP) vont de pair, et dans la plupart des langues, les Mocks fonctionnent mieux en découplant les classes au moyen d'interfaces.

Dans votre exemple, cela fonctionnera sans que vous ayez besoin de changer de code: (Edit: je veux dire qu'à l'avenir, si vous concevez votre application de cette manière, vous n'aurez pas besoin de changer de code pour les dépendances fictives :))

  • Résumé une iDude interface
  • classes concrètes FatDude (et MockFatDude) devraient mettre en œuvre l'interface iDude
  • fournir un mécanisme pour une instance iDude être 'ensemble' ou injecté dans CLASSA - injection de dépendance (constructeur ou obtenir/ensembles); ou mieux (pour remplacer un ClassFactory en béton)

Notez également le travail de modèle de service de localisation que de nombreux (voir moq et al) des cadres moqueurs vous permettent réellement de construire la classe concrète Mock « à la volée », afin que vous puissiez créez la fonctionnalité de MockFatDude directement dans votre test unitaire.

+0

@noonb: Je pense qu'il impliquait l'abstraction dans sa solution d'exemple, sinon il aurait eu besoin d'un override. –

+0

Comme le code ci-dessus ressemble à Java plutôt que C#, je vais ajouter un lien vers http://stackoverflow.com/questions/22697/whats-the-best-mock-framework-for-java –

+0

Merci pour le pointe! –

2

Oui. Vous avez trébuché sur un bon design directement à cause de votre test unitaire. Si vous regardez de plus près, vous verrez que vous avez supprimé le couplage entre classA et FatDude. Maintenant FatDude peut être une interface pour le comportement qui est passé en cas de besoin. ClassA n'a pas besoin de savoir quel genre de FatDude il obtient, ou comment construire un FatDude (avec cheeseburgers?).

Votre solution est exactement ce que j'aurais fait. Il n'y a rien de mal à changer votre code pour accommoder TDD, aussi longtemps que vous comprenez les raisons et les avantages/inconvénients de faire de tels changements.

+0

Merci pour le conseil! –

+0

@ masato-san: de rien! –