2009-09-23 8 views
0

J'ai le code suivant (simplifié).Comment mocker appel de méthode d'une autre classe dans Rhino Mock AAA?

public class OrderProcessor 
{ 
    public virtual string PlaceOrder(string test) 
    { 
     OrderParser orderParser = new OrderParser(); 
     string tester = orderParser.ParseOrder(test); 
     return tester + " here" ; 
    } 

} 

public class OrderParser 
{ 

    public virtual string ParseOrder(string test) 
    { 
     if (!string.IsNullOrEmpty(test.Trim())) 
     { 
      if (test == "Test1") 
       return "Test1"; 
      else 
      { 
       return "Hello"; 
      } 
     } 
     else 
      return null; 
    } 
} 

Mon test est la suivante -

public class OrderTest 
    { 
     public void TestParser() 
     { 
     // Arrange 

     var client = MockRepository.GenerateMock<OrderProcessor>(); 
     var spec = MockRepository.GenerateStub<OrderParser>(); 

     spec.Stub(x => x.ParseOrder("test")).IgnoreArguments().Return("Test1"); 

     //How to pass spec to client so that it uses the same. 

     } 
    } 

Maintenant, comment puis-je tester le client afin qu'il utilise la méthode moqué de OrderParser. Je peux mock le OrderParser mais comment puis-je passer cela à la classe mocked orderProcessor?

Faites-le moi savoir s'il vous plaît.

Merci d'avance.

Répondre

1

Je suis un peu perturbé par votre test puisque vous ne testez pas vraiment autre chose que RhinoMocks. Vous créez deux simulacres et ensuite faites quelques affirmations sur eux. Vous n'avez même pas testé vos vraies classes.

Vous devez effectuer une injection de dépendance si vous voulez vraiment obtenir un bon test unitaire. Vous pouvez rapidement refactoriser votre code pour utiliser les interfaces et l'injection de dépendances pour valider votre test.

Commencez par extraire une interface de votre classe OrderParser:

public interface IOrderParser 
{ 
    String ParseOrder(String value); 
} 

Maintenant, assurez-vous que votre classe OrderParser implémente cette interface:

public class OrderParser: IOrderParser{ ... } 

Vous pouvez maintenant factoriser votre classe BonCommande à prendre dans une instance d'un objet IOrderParser à travers son constructeur. De cette façon, vous "injectez" la dépendance dans la classe.

public class OrderProcessor 
{ 
    IOrderParser _orderParser; 

    public OrderProcessor(IOrderParser orderParser) 
    { 
     _orderParser = orderParser; 
    } 

    public virtual string PlaceOrder(string val) 
    { 
     string tester = _orderParser.ParseOrder(val); 
     return tester + " here" ; 
    } 
} 

Lors de votre test, vous voulez uniquement simuler la dépendance et non le SUT (Sujet à tester). Votre test ressemblerait à quelque chose comme ceci:

public class OrderTest 
    { 
     public void TestParser() 
     { 
     // Arrange 

     var spec = MockRepository.GenerateMock<IOrderParser>(); 
     var client = new OrderProcessor(spec); 

     spec.Stub(x => x.ParseOrder("test")).IgnoreArguments().Return("Test1"); 

     //Act 
     var s = client.PlaceOrder("Blah"); 

     //Assert 
     Assert.AreEqual("Test1 Here", s); 

     } 
    } 

Il est difficile pour moi d'évaluer ce que vous essayez de faire avec vos classes, mais vous devriez être en mesure d'obtenir l'idée de cette situation. Quelques axiomes à suivre:

  1. utiliser des interfaces et de la composition héritage
  2. Utilisation dependency injection des dépendances externes (inversion de contrôle)
  3. test une seule unité, et moquer ses dépendances
  4. Seulement moquer un niveau des dépendances. Si vous testez la classe X qui dépend de Y qui dépend de Z, vous ne devriez moquez Y et jamais Z.
  5. toujours test behavior et jamais les détails de mise en œuvre

Vous semblez être sur la bonne voie, mais besoin d'un peu d'orientation. Je suggère de lire le matériel que Martin Fowler, et Bob Martin doivent se mettre à jour.

Questions connexes