2011-03-31 3 views
1

Voici mon problème:Comment utiliser les mocks dans ce cas?

J'ai une application n-tiers pour laquelle je dois écrire des tests unitaires. Les tests unitaires concernent la couche de gestion.

J'ai une méthode à tester appelée Insert() et celle-ci utilise deux méthodes protégées de l'héritage et appelle directement une méthode de la couche d'accès aux données. J'ai donc fait un faux objet pour le DAL. Mais voici le point, dans un (edit :) protégé méthode de l'héritage, Il utilisera un autre objet de DAL! Il semble qu'il n'est pas possible de se moquer de celui-ci!

Voici la méthode pour le code de test:

public int Insert(MYOBJECT aMyObject) 
    { 
      //first inherited method use the FIRSTDALOBJECT so the mock object --> No problem 
      aMyObject.SomeField= FirstInherited(); 

      //Second inherited method (see after) --> my problem 
      aMyObject.SomeOtherField = SecondInherited(); 

      // Direct access to DALMethod, use FIRSTDALOBJECT so the mock -->No Problem 
      return this.FIRSTDALOBJECT.Insert(aMyObject);    
    } 

Voici la méthode SecondInherited:

protected string SecondInherited() 
    { 
     // Here is my problem, the mock here seems not be possible for seconddalobject           
     return (new SECONDDALOBJECT Sdo().Stuff()); 
    } 

Et voici le code de la méthode de test unitaire:

[TestMethod()] 
    public void InsertTest() 
    { 
     BLLCLASS_Accessor target = new BLLCLASS_Accessor(); 
     MYOBJECT aMyObject = new MYOBJECT { SomeField = null, SomeOtherField = 1 }; 
     int expected = 1; 
     int actual; 

     //mock 
     var Mock = new Mock<DAL.INTERFACES.IFIRSTDALOBJECT>(); 
     //Rec for calls 
     List<SOMECLASS> retour = new List<SOMECLASS>(); 
     retour.Add(new SOMECLASS()); 

     //Here is the second call (last from method to test) 
     Mock 
      .Setup(p => p.Insert(aMyObject)) 
      .Returns(1); 

     // Here is the first call (from the FirstInherited()) 
     Mock 
      .Setup(p => p.GetLast()) 
      .Returns(50); 
     // Replace the real by the mock 
     target.demande_provider = Mock.Object; 

     actual = target.Insert(aMyObject); 
     Assert.AreEqual(/*Some assertion stuff*/); 
    } 

Merci pour avoir lu toute la question :-) J'espère que c'est assez clair.

Répondre

3

Votre texte semble dire que SecondInherited est private, alors que dans l'exemple de code est protected. Quoi qu'il en soit, si ce n'est pas protected, je suggère de changer son qualificatif d'accès comme première étape.

Vous pouvez créer une sous-classe uniquement à des fins de test, et passer outre SecondInherited il pour éviter de créer SECONDDALOBJECT et juste retourner une valeur appropriée pour vos tests.

De cette façon, vous pouvez écrire votre (vos) premier (s) test (s) unitaire avec un minimum de changements dans la classe testée, minimisant ainsi les chances de casser quelque chose. Une fois que vous avez mis en place les tests unitaires, ceux-ci vous permettent de faire plus de refactoring en toute sécurité, pour finalement obtenir une meilleure conception (plus testable/simulable), comme en utilisant Dependency Injection, ou une usine. (Je préférerais probablement un Abstract Factory sur Factory Method ici, car ce dernier vous obligerait pratiquement à garder sous-classe la classe testée).

Le livre fondamentalement recommandé pour l'apprentissage de cette technique (et beaucoup d'autres) est Working Effectively With Legacy Code.

+0

Il est protégé, désolé pour mon erreur .. – bAN

+0

+1: Bonne solution pour des résultats rapides –

+0

@bAN, merci pour la clarification, de cette façon la solution est encore plus facile. –

2

Aucune chance de se moquer de cela avec MOQ. Vous avez deux options:

  1. Utilisez Typemock ou taupes pour se moquer de la classe SECONDDALOBJECT
  2. Refactor le code, de sorte que l'instance de SECONDDALOBJECT est pas créé dans la façon dont il est, mais d'une manière qui peut être moqué (méthode Factory, DI, ...) (preféré!)
Questions connexes