2008-12-11 4 views
4

Je me demande si les instructions Unittesting et using peuvent vraiment aller de pair car il n'y a aucun moyen de se moquer de l'objet jetable instancié dans l'instruction using. Comment serais-je en mesure de désamorcer efficacement une méthode contenant l'instruction using suivante?Méthodes de désinsertion qui contiennent des instructions d'utilisation

 
public void MyMethod() 
{ 
    using(MyDisposableClass disp = new MyDisposableClass()) 
    { 
     ... 
    } 
} 

Est-ce que l'utilisation d'instructions est simplement interdite lorsque vous testez un appareil?

Tout commentaire apprécié.

+0

bien q. les alternatives que je peux penser sont plus de travail que l'original .. – Gishu

Répondre

4

Non, l'utilisation d'instructions n'est certainement pas interdite. Mais que fait réellement MyDisposableClass? Il me semble que ce n'est pas vraiment une question d'utilisation de l'instruction qui pose un problème - c'est une question de méthode de création d'un nouvel objet que vous voulez mocker - c'est le problème.

Avez-vous vraiment besoin de vous moquer de MyDisposableClass? Peut-il être transmis à MyMethod au lieu d'être créé à l'intérieur? Comme toujours, l'astuce consiste à trouver comment accrocher dans le processus et injecter vos propres objets lorsque vous avez besoin de ...

+0

MyDisposableClass est vraiment un adaptateur à un système externe que j'ai besoin de Connect(), Login() et LogOut() sur disposer. Si je l'expédie en tant que paramètre, je rencontre un problème dans la méthode parente, n'est-ce pas? – Fadeproof

+0

Certainement * quelque chose * a besoin de le créer. Vous devez essentiellement trouver le meilleur crochet pour cela. Malheureusement, il est difficile de vous dire * exactement * où injecter l'objet sans en savoir plus sur votre système que nous avons probablement le temps de voir ici :( –

3

Puisque vous voulez moquer la classe des ressources que je suppose que vous avez déjà

interface IResource : IDisposable 
{ 
     void DoSomething(); 
} 

class DisposableResource : IResource 
{ 
    public void Dispose()  { Console.WriteLine("That's it. I'm outta here!"); } 
    public void DoSomething() { Console.WriteLine("Hard work this"); } 
} 

Pour pouvoir injecter l'obj, vous avez besoin d'une couture .. ie GetResource()

class MyClass 
{ 
    protected virtual IResource GetResource() 
    { 
     return new DisposableResource(); 
    } 
    public void MyMethod1() 
    { 
     using (IResource r = GetResource()) 
     { 
      r.DoSomething(); 
     } 
    } 
} 

Dans votre code de test, il vous suffit de sous-classer et de surcharger GetResource() pour renvoyer un mock.

class MySubClassForTest : MyClass 
{ 
    protected override IResource GetResource() 
    { 
     return new MockResource(); 
    } 
} 
class MockResource : IResource // or use a mock framework to create one 
{ 
    public void DoSomething()  { Console.WriteLine("Me work?"); } 
    public void Dispose()   { Console.WriteLine("Disposed Mock!"); } 
} 

C'est tout.

MyClass obj = new MyClass();   // production code 
obj.MyMethod1(); 

obj = new MySubClassForTest();   // test code 
obj.MyMethod1(); 
1

TypeMock vous permettra de simuler ceci. Il fonctionne en modifiant l'IL à la volée et n'a donc aucun problème à se moquer des choses que vous ne pouvez pas rater autrement.

Mais même avec TypeMock, vous devriez toujours jeter un oeil à ce que Jon Skeet et Pop Catalin disent ci-dessus. Votre code sera plus facile à maintenir, si vous essayez de réduire le nombre de dépendances.

Questions connexes