2010-03-01 5 views
1

Je suis en train d'écrire un test unitaire pour la fonction « IsUnique » dans la classe ci-dessous qui ressemble à ceci:Comment faire pour affirmer une méthode privée sur une classe concrète est appelée (TypeMock/NMock/etc ..)?

class Foo 
{ 
    public bool IsUnique(params...) 
    { 
     ValidateStuffExists(params); 
     return CheckUniqueness(params); 
    } 

    private void ValidateStuffExists(params) 
    { 
     //does some validation 
    } 

    private bool CheckUniqueness(params) 
    { 
     //does logic to determine if its unique per params 
     return result; 
    } 

} 

La seule chose que je veux tester ici est que ValidateStuffExists et CheckUniqueness est appelé et a passé la arguments. C'est tout ce que fait cette fonction, donc c'est tout ce que je vais tester (je plierai la règle psuedo de 'tester le comportement public' et testerai les méthodes privées ici, parce qu'elles ont une grande méthode/tests compliqués ou testent 2 private méthodes).

Je suis ouvert à toute bibliothèque de moquerie. J'utilise NMock et je ne pensais pas que c'était pour la tâche - alors j'ai téléchargé TypeMock comme j'ai lu et entendu que c'était le meilleur et qu'il pouvait mocker même des classes concrètes/appels de méthodes non-interface ...

que je fais quelque chose comme ça dans mon test et il émet une exception à la ligne « Isolate.WhenCalled »:

 CrmEntityUniqueValidator_Accessor target = new CrmEntityUniqueValidator_Accessor(); // TODO: Initialize to an appropriate value 
     DynamicEntity entity = null; // TODO: Initialize to an appropriate value 
     string[] propertyNames = null; // TODO: Initialize to an appropriate value 

     bool tru = true; 
     Isolate.WhenCalled(() => target.CheckUniqueness(entity, propertyNames, null, null)).WillReturn(tru); 

     target.ValidatePropertiesExist(entity, propertyNames); 

     Isolate.Verify.WasCalledWithArguments(() => target.ValidatePropertiesExist(entity, propertyNames)); 
     Isolate.Verify.WasCalledWithArguments(() => target.CheckUniqueness(entity, propertyNames, null, null)); 

cela jette une exception comme « *** WhenCalled ne prend pas en charge une méthode appel en tant qu'argument. "

Même si je suis capable de faire la même chose avec une classe CLR - je peux railler sur DateTime.Now faire (code fonctionne):

 DateTime endOfWorld = new DateTime(2012, 12, 23); 
     Isolate.WhenCalled(() => DateTime.Now).WillReturn(endOfWorld); 
     DateTime dt = DateTime.Now; 

     Assert.AreEqual(dt, endOfWorld); 

Quelqu'un a des conseils ici? Dois-je séparer ces deux méthodes en une classe séparée et faire une interface est le seul moyen? ou compliquer ma méthode/tests ??? Il doit y avoir quelque chose qui me manque ici ... Merci beaucoup pour toute aide à l'avance.

EDIT: Je suppose que j'essaie d'esquiver les 2 méthodes privées de la classe pour le test unitaire. Comment est-ce que je pourrais faire ceci sans devoir séparer ces 2 méthodes dans une classe/interface séparée?

Répondre

3

essayer Isolate.NonPublic.WhenCalled (objet, "méthode non publique"). IgnoreCall

ou Isolate.Verify.NonPublic.WasCalled (objet, "méthode" ..

+0

C'est ce que je cherchais ... mais il ne semble pas fonctionner .. Je l'ai fait: Isolate.NonPublic.WhenCalled (cible, "ValidatePropertiesExist") IgnoreCall(); mais ... lorsque la fonction est appelée, elle. va dans le code actuel ... Des idées pourquoi? La fonction prend 3 params (que je ne spécifie nulle part), je me demande si cela a à voir avec ça ... ? – dferraro

+0

J'ai également essayé d'utiliser un Accesseur pour la classe au lieu de la classe réelle (en utilisant MSTEST ici), et j'ai fait un 'Called Call' normal. J'ai fait: Isolate.WhenCalled (() => target.CheckUnicité (entity, propertyNames, retrieveHelper, service)). WillReturn (true); où 'cible' est mon Foo_Accessor. Cela me donne cette exception: "*** WhenCalled ne prend pas en charge l'utilisation d'un appel de méthode en tant qu'argument. - Pour résoudre ce problème passe faux au lieu de CrmEntityUniqueValidator_Accessor.CheckUniqueness() » Ce qui n'a pas de sens, puisque je ne porte pas de toute méthode appelle comme params ... – dferraro

+0

êtes-vous sûr que vous utilisez ce avec Typemock activés dans Visual Studio? si vous l'exécutez à partir d'un outil externe en dehors de VS, vous devriez utiliser tmockrunner.exe – RoyOsherove

0

RhinoMocks a la méthode AssertWasCalled qui peut servir dans le but de garantir qu'une méthode appelle une autre méthode ... mais je ne suis pas sûr que vous pouvez le faire sur une fonction privée de la même classe que vous êtes des tests unitaires. Je pense que vous ne pourriez le faire que si les deux méthodes que vous vouliez utiliser étaient dans une autre classe de dépendance qui a été injectée.

Questions connexes