¿Cómo permito que el ensamblaje (prueba de unidad uno) acceda a las propiedades internas de otro ensamblaje?

80

Me gustaría que mi ensamblaje Core no exponga una determinada clase y aún me gustaría poder probarlo. Cómo puedo hacer eso ?

Tomas Pajonk
fuente

Respuestas:

107

InternalsVisibleTo atribuir al rescate!

Solo agrega:

[assembly:InternalsVisibleToAttribute("UnitTestAssemblyName")]

a su archivo AssemblyInfo.cs de clases principales

Consulte Friend Assemblies (Guía de programación de C #) para conocer las mejores prácticas.

aku
fuente
3
Acabo de hacer esto con éxito con un ensamblado con nombre fuerte siguiendo la guía a la que se vincula aku. Sin embargo, tuve un problema. Después de configurar todo, tuve que reiniciar Visual Studio para que Intellisense funcionara. Se compilaría antes de reiniciar pero siempre mostraría las líneas rojas.
Eric Schoonover
20

Con InternalsVisible, si sus ensamblados tienen un nombre fuerte, debe especificar la clave pública (nota: la clave completa, no el token de clave pública) por ejemplo ...

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("BoardEx_BusinessObjects.Tests, 
  PublicKey=0024000004800000940000000602000000240000525341310004000001000100fb3a2d8 etc etc")]

y el siguiente truco es realmente útil para obtener la clave pública sin recurrir a la línea cmd ...

http://www.andrewconnell.com/blog/archive/2006/09/15/4587.aspx

Simon Keep
fuente
9

Pongo mis pruebas unitarias en el mismo ensamblaje que el código que está probando. Esto tiene sentido para mí, porque pienso en "probarse a sí mismo" como una característica de una clase, junto con cosas como "inicializarse" y "describirse a sí mismo".

He escuchado algunas objeciones a este enfoque, pero pocas de ellas han sido convincentes.

Duele el rendimiento ¡ Bah, digo! ¡No optimice sin datos duros! Quizás si planea descargar sus ensamblajes a través de enlaces lentos, entonces valdría la pena minimizar el tamaño del ensamblaje.

Es un riesgo de seguridad . Solo si tienes secretos en tus pruebas. No hagas eso.

Ahora, tu situación es diferente a la mía, así que tal vez tenga sentido para ti y tal vez no. Tendrá que averiguarlo usted mismo.

Aparte: en C #, una vez intenté poner mis pruebas unitarias en una clase llamada "Pruebas" que estaba anidada dentro de la clase que estaba probando. Esto hizo evidente la correcta organización de las cosas. También evitó la duplicación de nombres que ocurre cuando las pruebas para la clase "Foo" están en una clase llamada "FooTests". Sin embargo, los marcos de prueba unitarios a los que tuve acceso se negaron a aceptar pruebas que no estuvieran marcadas como "públicas". Esto significa que la clase que estás probando no puede ser "privada". No puedo pensar en ninguna buena razón para exigir que las pruebas sean "públicas", ya que nadie realmente las llama métodos públicos, todo es a través de la reflexión. Si alguna vez escribe un marco de prueba unitario para .Net, considere la posibilidad de permitir pruebas no públicas, ¡por mi bien!

Jay Bazuzi
fuente
5
Enfoque interesante. Y estoy totalmente de acuerdo con que las pruebas sean públicas. Estúpido requisito, en mi opinión.
Kilhoffer
@Kilhoffer: Me he estado quejando de eso durante años y eres la primera persona que está realmente de acuerdo conmigo. ¡Gracias!
Jay Bazuzi
6
Si usa [Conditional("DEBUG")]en clases de prueba, entonces no deberían estar en el ensamblaje de producción y no afectar el rendimiento.
xmedeko
3

Sugeriría no tener tales problemas ... si realmente desea probar unitariamente sus clases "internas", simplemente escóndelas en un espacio de nombres que solo su código interno terminaría usando. A menos que esté escribiendo un marco en la escala del marco .NET, realmente no necesita ese nivel de ocultación.

Joel martinez
fuente
Iba a comentar exactamente lo que dijiste cuando noté tu comentario en la parte inferior. +1! :)
Bjorn Reppen
2

Puede usar la reflexión (como lo hacen los elementos de prueba de MS), o puede declarar que el ensamblaje de prueba de la unidad es un amigo del ensamblaje principal.

La otra opción es poner las pruebas unitarias en el mismo ensamblaje.

Dan Blair
fuente