2012-02-21 13 views
5

Estoy intentando probar la unidad de una función privada en .net. Esta función privada devuelve una colección del tipo myClass, que es una clase interna.InternalsVisibleTo parece ignorado

He utilizado el atributo de ensamblaje InternalsVisibleTo, por lo que el tipo myClass es conocido por mi proyecto de prueba.

Aquí está el código que quiero prueba:

namespace MyProject 
{ 
    public class Class1 
    { 
     private List<myClass> myFunction() 
     { 
      return new List<myClass>(); 
     } 

     internal class myClass 
     { 
      public int MyProperty { get; set; } 
     } 
    } 
} 

[TestMethod()] 
[DeploymentItem("MyProject.dll")] 
public void myFunctionTest() 
{ 
    Class1_Accessor target = new Class1_Accessor(); 
    List<Class1_Accessor.myClass> expected = null; 
    List<Class1_Accessor.myClass> actual; 
    actual = target.myFunction(); 
    Assert.AreEqual(expected, actual); 
    Assert.Inconclusive("Verify the correctness of this test method."); 
} 

y en mi montaje de archivo de información:

[assembly: InternalsVisibleTo("MyProject.Test")] 

Así que ¿por qué establece Visual Studio del tipo de la lista para Class1_Accessor.myClass desde myClass es conocida a mi proyecto de prueba?

Por eso obtengo un error de tiempo de ejecución (no se puede convertir el tipo myClass en tipo Class1_Accessor.myClass).

Debido myFunction es privada, VisualStudio genera el siguiente código (que está muy bien para la mayor parte de ella)

[Shadowing("MyProject.Class1")] 
public class Class1_Accessor : BaseShadow 
{ 
    protected static PrivateType m_privateType; 

    [Shadowing("[email protected]")] 
    public Class1_Accessor(); 
    public Class1_Accessor(PrivateObject value); 

    public static PrivateType ShadowedType { get; } 

    public static Class1_Accessor AttachShadow(object value); 
    [Shadowing("[email protected]")] 
    public List<Class1_Accessor.myClass> myFunction(); 

    [Shadowing("MyProject.Class1+myClass")] 
    public class myClass : BaseShadow 
    { 
     protected static PrivateType m_privateType; 

     [Shadowing("[email protected]")] 
     public myClass(); 
     public myClass(PrivateObject value); 

     [Shadowing("MyProperty")] 
     public int MyProperty { get; set; } 
     public static PrivateType ShadowedType { get; } 

     public static Class1_Accessor.myClass AttachShadow(object value); 
    } 
} 

Sin embargo, no entiendo por qué contiene una nueva definición de myClass, ya que es una clase interna, que no debería necesitar ningún descriptor de acceso. Esta es la raíz del problema en mi opinión.

+0

Es posible que desee agregar la etiqueta 'mstest' para atraer la atención de aquellos que tienen experiencia en el uso de Accessors. No estaba seguro de qué etiqueta eliminar, así que no edité las etiquetas yo mismo. Nunca me interesaron mucho los accesorios, así que tengo poca experiencia. (Además, hay un fuerte sentimiento de que no debe probar miembros privados, si tiene un miembro privado que no es verificable indirectamente a través de uno público, entonces es una señal de que debe extraer una clase separada para esa lógica). – phoog

+0

gracias , He agregado la etiqueta. Probar a los miembros privados o no es un tema totalmente diferente (aunque tienes razón). Sin embargo, todavía quiero probar esa función. – Sam

+0

En cuanto a las pruebas de miembros privados, el hecho de que sea un tema completamente diferente es la razón por la que puse eso entre paréntesis. Y, por supuesto, siempre hay excepciones defendibles a directrices como esa. Añadiría que cuando * he probado * miembros privados, en general solo he usado la reflexión, incluso tengo algunos métodos de ayuda para este propósito (por ejemplo, 'CallNonPublicMethod (string methodName)'). Me resulta más fácil de tratar que los accesorios: nunca imaginé cómo regenerarlos cuando modifiqué las clases que estaban sombreando. – phoog

Respuesta

0

InternalsVisibleTo no hace que los miembros privados sean visibles para los ensamblajes de amigos. Funciona en miembros/tipos marcados como internos. Verifique los documentos here.

actualización

probar este (según este doc): regenerar su clase de prueba, en el cuadro de diálogo Crear prueba Unidad, haga clic en Configuración. En la configuración de generación de pruebas asegurarse de que el honor InternalsVisibleTo Atributo casilla está marcada

+1

Por favor, lea mi pregunta nuevamente. el tipo myClass IS Internal, NOT private. Es solo el método que quiero probar que es privado. – Sam

+2

En su código, myFunction es privado. – Fernando

+0

sí, myFunction es privado, por lo que es normal que VisualStudio cree un acceso para él. Sin embargo, myClass es interno (y marcado como amigo en el archivo de ensamblaje), por lo que no entiendo por qué VisualStudio crea un acceso para él. – Sam

4

no puede convertir el tipo myClass para escribir Class1_Accessor.myClass

dice todo lo que necesita saber: simplemente - que tiene dos definiciones diferentes de myClass. Los tipos tienen un alcance por ensamblaje; el [InternalsVisibleTo(...)] lo hace accesible, pero más allá de eso: como de costumbre.

Encuentra qué/donde se tiene una segunda myClass, y uno de:

  • disambiguate (espacio de nombres a calificar etc)
  • cambiar el nombre de uno de ellos
  • desmontar uno de ellos si significan lo mismo cosa, y se duplican de forma incorrecta

Esto es exactamente lo mismo que tener:

namespace A { class Foo {} } 
namespace B { class Foo {} } 

que son dos clases completamente no relacionadas llamadas Foo, y la conversión entre ellas fallará.

Cuestiones relacionadas