2009-04-16 5 views
0

J'ai deux classes comme celle-ci (dans le projet actuel):Comment puis-je empêcher des arguments génériques d'être sali par des tests VS2008 unité

namespace app { 
    internal class A { 
    } 

    internal class B { 
     private List<A> list; 
     private void SomeMethodToTest() { 
      list = new List<A>() { new A() }; 
     } 
    } 

Le Je me cherche quelque chose comme test de l'unité

[TestClass()] 
public class ATest { 
    [TestMethod()] 
    public void TestSomeMethod() { 
     B_Accessor b = new B_Accessor(); 
     b.SomeMethodToTest(); 
     Assert.AreEqual(1, b.list.Count); // ERROR ON THIS LINE 
    } 
} 

Sur la ligne marquée, j'obtiens une exception InvalidCastException disant quelque chose comme "impossible de convertir un objet de type System.Collections.Generic.List'1 [app.A] en type System.Collections.Generic.List'1 [app.A_Accessor ]

Le problème est que, parce que A est interne, la B_Accessor classe générée automatiquement ressemble

[Shadowing("app.B")] 
public class B_Accessor : BaseShadow { 
    ... stuff ... 

    [Shadowing("list")] 
    public List<A_Accessor> list { get; set; } 

    ... stuff ... 
} 

Notez que, dans la classe accesseur, la liste est de type Liste <A_Accessor> et non List <A>. J'ai spécifié l'attribut InternalsVisibleTo sur l'application, afin que le projet de test puisse accéder au type A, mais pour une raison quelconque, VS le remplace par le type d'accesseur, ce qui rend le type incompatible avec le type encapsulé.

Comment puis-je contourner cela autre que de rendre un public?

Répondre

0

J'ai supprimé ma réponse précédente car je n'avais pas remarqué que vous utilisiez déjà InternalsVisibleToAttribute.

Qu'est-ce qui génère ces classes "accesseur"? Quand vous dites "VS le remplace par le type d'accesseur" voulez-vous dire qu'il change votre code source? Cela semble très étrange - que se passe-t-il si vous le remettez à simplement utiliser A et B au lieu de A_Accessor et B_Accessor?

Si vous pouvez éventuellement vous débarrasser des classes générées automatiquement qui sont signifiait pour ressembler aux vrais, mais ne pas tout à fait, puis se débarrasser d'eux. Je soupçonne que c'est juste une situation où ils vont causer des problèmes.

Je n'ai jamais eu de problème en utilisant InternalsVisibleTo et en testant directement les membres internes. (Eh bien, R # attrapaient parfois confondu dans une version précédente, mais à part ça ...)

+0

VS génère les classes accesseurs automagiquement lorsque la projet de test est construit. Je ne peux pas utiliser B au lieu de B_Accessor puisque je veux accéder à un membre privé. – erikkallen

+0

OK, alors comment tester une méthode privée? Je préférerais ne pas casser l'encapsulation pour que le test fonctionne. – erikkallen

+0

http://stackoverflow.com/questions/250692/how-do-you-unit-test-private-methods – JeffH

0

Il est possible de remplacer le projet de test avec quelque chose comme

internal static class AccessorExtensionMethods { 
    internal static List<A> Get_list(this PrivateObject po) { 
     return (List<A>)po.GetField("list"); 
    } 
} 

[TestClass()] 
public class ATest { 
    [TestMethod()] 
    public void TestSomeMethod() { 
     PrivateObject bpo = new PrivateObject(new B()); 
     B_Accessor b = new B_Accessor(bpo); 
     b.SomeMethodToTest(); 
     Assert.AreEqual(1, bpo.Get_list().Count); 
    } 
} 
Questions connexes