2010-10-07 3 views
0

J'ai une classe qui hérite d'une classe de base abstraite. J'essaie de vérifier qu'une méthode protégée spécifiée dans la classe de base est appelée deux fois et je voudrais vérifier que les paramètres passés sont des valeurs spécifiques (différentes pour chaque appel). J'espérais pouvoir utiliser Protected avec Expect ou Verify, mais apparemment j'ai manqué ce qui peut être fait avec ces méthodes.Vérifiez qu'une méthode protégée par une base est appelée avec Moq 3.1

Est ce que j'essaye possible avec moq?

MISE À JOUR: Un exemple de ce que je suis en train de faire:

class MyBase 
{ 
    protected void SomeMethodThatsAPainForUnitTesting(string var1, string var2) 
    { 
     //Stuf with file systems etc that's very hard to unit test 
    } 
} 

class ClassIWantToTest : MyBase 
{ 
    public void IWantToTestThisMethod() 
    { 
     var var1 = //some logic to build var 1 
     var var2 = //some logic to build var 2 
     SomeMethodThatsAPainForUnitTesting(var1, var); 
    } 
} 

Essentiellement, je veux tester la façon dont les variables var1 et var2 sont créées correctement et est passé dans SomeMethodThatsAPainForUnitTesting, donc essentiellement I Vous voulez simuler la méthode protégée, vérifiez qu'elle a été appelée au moins une fois et que tous les paramètres ont été transmis correctement. Si cela appelait une méthode sur une interface, ce serait trivial, mais je suis en train de décoller avec une méthode protégée.

Je ne peux pas facilement changer le design car c'est le développement de champs bruns et je ne suis pas la seule classe qui appelle la méthode.

+0

Merci de votre clarification. J'ai enlevé ma réponse car elle n'a pas résolu le problème. –

Répondre

1

Non ce n'est pas possible.

Des outils tels que les mocks Moq et Rhino fonctionnent de manière magique en générant des sous-classes de types que vous voulez simuler lors de l'exécution. Ils génèrent toutes leurs logiques "Verify" et "Expect" en remplaçant un membre (dans le cas de membres virtuels) ou en l'implémentant (dans le cas d'une interface) et en insérant du code pour inspecter ou enregistrer les arguments passés Une réponse toute faite.

Alors, que pouvez-vous faire pour contourner ce problème? Tout d'abord si vous pouvez modifier la méthode de base à ce virtuel alors vous permettra de tester votre méthode en créant un harnais de test comme ceci: -

class ClassIWantToTestHarness : ClassIWantToTest { 
    public string Arg1 { get; set; } 
    public string Arg2 { get; set; } 
    public int CallCount { get; set; } 

    protected override void SomeMethodThatsAPainForUnitTesting(var1, var2) { 
     Arg1 = var1; 
     Arg2 = var2; 
      CallCount++; 
    } 
} 

[Test] 
public void ClassIWantToTest_DoesWhatItsSupposedToDo() { 
    var harness = new ClassIWantToTestHarness(); 
    harness.IWantToTestThisMethod(); 
    Assert.AreEqual("Whatever", harness.Arg1); 
    Assert.AreEqual("It should be", harness.Arg2); 
    Assert.IsGreaterThan(0, harness.CallCount); 
} 

S'il est impossible de modifier la classe de base du tout en raison de la le code étant si horriblement brownfield que vous ne voulez pas salir vos chaussures, vous pouvez simplement envelopper la méthode dans ClassIWantToTest comme une méthode virtuelle protégée et effectuer le même tour à la place. Moq peut prendre en charge le remplacement des membres virtuels protégés (voir la section divers here) - bien que personnellement je préfère les faisceaux de test manuels dans ce cas.

Questions connexes