2017-07-04 4 views
1

Chers utilisateurs de RhinoMocks. Je suis un débutant à RhinoMocks et ai un problème pour envelopper ma tête autour de quelque chose. J'ai besoin de tester deux méthodes dans une classe, l'une d'entre elles appelle l'autre plusieurs fois. J'ai déjà testé celui appelé plusieurs fois séparément, la configuration est quelque peu complexe, donc l'idée de tester l'autre méthode était de remplacer la méthode qui a déjà été testée. Voici un exemple minimal:RhinoMocks VerifyAllExpectations échoue pour plusieurs attentes sur la méthode stubbed

 public class TestedClass 
    { 
     public virtual void DoSthOnce(List<int> listParam) 
     { 
      foreach (var param in listParam) 
       DoSthMultipleTimes(param); 
     } 

     public virtual void DoSthMultipleTimes(int intParam) 
     { 
      Console.WriteLine("param: " + intParam); 
     } 
    } 

à savoir DoSthMultipleTimes() est déjà testé. Le code de test suivant fonctionne et vérifie que le DoSthMultipletimes() -Method a été appelé pour chaque élément de la liste qui a été fourni en tant que paramètre à DoSthOnce().

var paramList = Enumerable.Range(1, 10).ToList(); 
    var mock = MockRepository.GeneratePartialMock<TestedClass>(); 
    mock.Stub(m => m.DoSthMultipleTimes(Arg<int>.Is.Anything)) 
     .WhenCalled(mi => 
     { 
      // Only for debug; this method is empty in the actual test code. 
      Console.WriteLine("Stub called with " + mi.Arguments[0]); 
     }); 

    mock.DoSthOnce(paramList); 

    // This will not throw an exception 
    foreach (var param in paramList) 
     mock.AssertWasCalled(m => m.DoSthMultipleTimes(param)); 

La sortie est comme prévu:

Stub called with 1 
    Stub called with 2 
    Stub called with 3 
    Stub called with 4 
    Stub called with 5 
    Stub called with 6 
    Stub called with 7 
    Stub called with 8 
    Stub called with 9 
    Stub called with 10 

Cependant, ce qui suit échoue lancer une exception bien qu'il devrait être la même chose que ci-dessus, au moins de ma compréhension:

var paramList = Enumerable.Range(1, 10).ToList(); 
    var mock = MockRepository.GeneratePartialMock<TestedClass>(); 
    mock.Stub(/*same as above*/).WhenCalled(/*same as above*/); 
    foreach (var param in paramList) 
     mock.Expect(m => m.DoSthMultipleTimes(param)); 

    mock.DoSthOnce(paramList); 
    mock.VerifyAllExpectations(); 

La sortie de la console est identique, mais une exception ExpectationViolationException est renvoyée par VerifyAllExpectations(). Informations supplémentaires:

TestedClass.DoSthMultipleTimes(1); Expected #1, Actual #0. 
    TestedClass.DoSthMultipleTimes(2); Expected #1, Actual #0. 
    ... 
    TestedClass.DoSthMultipleTimes(10); Expected #1, Actual #0. 

Les paramètres sont corrects, mais quel est exactement le problème ici?

Répondre

0

Je devine en raison de votre talon lui-même.

Ce morceau de code enregistrerait les différentes attentes que vous voulez:

foreach (var param in paramList) 
    mock.Expect(m => m.DoSthMultipleTimes(param)); 

Cela fixerait l'espoir que DoSthMultipleTimes (1), DoSthMultipleTimes (2), etc sont appelés. Cependant, votre code Mock.Stub remplacera/talonnera l'implémentation elle-même. Cela a abouti à ce que Rhino exécute cette substitution/méthode (et n'appelle pas la méthode originale DoSthMultipleTimes de la classe d'origine). Ainsi, lorsque VerifyAllExpectation est appelé, aucune méthode de la classe d'origine n'a été appelée.

Vous pouvez vérifier ce qui précède en supprimant les éléments suivants:

mock.Stub(m => m.DoSthMultipleTimes(Arg<int>.Is.Anything)) 
    .WhenCalled(mi => 
    { 
     // Only for debug; this method is empty in the actual test code. 
     Console.WriteLine("Stub called with " + mi.Arguments[0]); 
    }); 

Puisque vous utilisez PartialMock, si vous n'êtes pas implémentez le talon, il appellerait la méthode originale. Et supposément, il passerait avec succès toutes les attentes. (NB: prenez garde lors de l'utilisation de PartialMock car il exécutera la méthode d'origine s'il n'est pas stubbed (par exemple: appel de base de données, etc.)).

+0

Merci beaucoup pour votre réponse. Je m'y attendais autant. Comme j'ai essayé de l'expliquer, la configuration pour avoir l'exécution originale de la méthode non-stubbed est quelque peu complexe et aboutirait à beaucoup de code de test en double. C'est pourquoi je voulais d'abord écraser la méthode. Cela signifie-t-il que je ne peux pas utiliser Expect dans ce cas particulier? – hickhack

+0

Je crois que vous ne seriez pas en mesure d'utiliser Expect dans ce cas particulier. Btw, si vous avez testé en utilisant le AssertWasCalled - que voulez-vous gagner en utilisant l'Expect? – hsoesanto

+0

Rien à gagner, juste essayer de comprendre. Merci! – hickhack