property - reflection c# español
¿Acceder a miembros internos a través de System.Reflection? (5)
Estoy tratando de probar la unidad de una clase que tiene muchas funciones internas. Obviamente, estos también necesitan pruebas, pero mi proyecto de Pruebas es independiente, principalmente porque cubre muchos proyectos pequeños y relacionados. Lo que tengo hasta ahora es:
FieldInfo[] _fields =
typeof(ButtonedForm.TitleButton).GetFields(
BindingFlags.NonPublic | BindingFlags.Instance |
BindingFlags.DeclaredOnly);
Console.WriteLine("{0} fields:", _fields.Length);
foreach (FieldInfo fi in _fields)
{
Console.WriteLine(fi.Name);
}
Esto escupe muy bien a todos los miembros privados, pero aún no muestra elementos internos. Sé que esto es posible, porque cuando estaba jugando con las pruebas autogeneradas que Visual Studio puede producir, me preguntó sobre qué hacer al mostrar las partes internas del proyecto de prueba. Bueno, ahora estoy usando NUnit y realmente me gusta, pero ¿cómo puedo lograr lo mismo con eso?
Al agregar el atributo InternalsVisibleTo assembly al proyecto principal, con el nombre del ensamblado del proyecto de prueba, los miembros internos deben ser visibles.
Por ejemplo, agregue lo siguiente a su ensamblaje fuera de cualquier clase:
[assembly: InternalsVisibleTo("AssemblyB")]
O para una orientación más específica:
[assembly:InternalsVisibleTo("AssemblyB, PublicKey=32ab4ba45e0a69a1")]
Tenga en cuenta que si su conjunto de aplicaciones tiene un nombre fuerte, su ensamble de prueba también necesitará un nombre fuerte.
Creo que debes preguntar si deberías escribir pruebas unitarias para métodos privados. Si escribe pruebas unitarias para sus métodos públicos, con una cobertura de código ''razonable'', ¿no está probando ya algún método privado que deba llamarse como resultado?
Al vincular las pruebas a métodos privados, las pruebas serán más frágiles. Debería poder cambiar la implementación de cualquier método privado sin romper ninguna prueba.
Refs:
http://weblogs.asp.net/tgraham/archive/2003/12/31/46984.aspx http://richardsbraindump.blogspot.com/2008/08/should-i-unit-test-private-methods.html http://junit.sourceforge.net/doc/faq/faq.htm#tests_11 http://geekswithblogs.net/geekusconlivus/archive/2006/07/13/85088.aspx
Su código solo muestra campos, por lo que espero que no muestre ningún miembro interno, ya que los campos siempre deben ser IMO privados. (Con la posible excepción de las constantes)
¿ButtonedForm.TitleButton realmente tiene algún campo no privado? Si está tratando de encontrar métodos internos , obviamente debe llamar a GetMethods
(o GetMembers
) para obtenerlos.
Como otros han sugerido, InternalsVisibleTo
es muy útil para probar (¡y casi exclusivamente para probar!). En cuanto a si debe probar los métodos internos, ciertamente me parece útil poder hacerlo. No considero que las pruebas unitarias sean exclusivamente pruebas de caja negra. A menudo, cuando sabe que la funcionalidad pública se implementa utilizando unos pocos métodos internos conectados de una manera simple, es más fácil realizar pruebas exhaustivas de cada uno de los métodos internos y algunas pruebas de "pseudointegración" en el método público.
Una justificación para usar el InternalsVisible está bajo mis circunstancias. Compramos el código fuente a un control de gráfico. Hemos encontrado dónde tenemos que hacer algunas modificaciones a ese control de fuente y compilar nuestra propia versión. Ahora, para asegurarnos de no romper nada, hay algunas pruebas de unidad que necesito escribir que necesitan acceso a algunos campos internos.
Este es un caso perfecto donde el InternalsVisible tiene sentido.
Me preguntaba, sin embargo, ¿qué harías si no tienes acceso a la fuente? ¿Cómo puedes llegar a un campo interno? .Net Reflector puede ver ese código, pero supongo que solo está mirando el IL.
Sería más apropiado utilizar el atributo InternalsVisibleTo
para otorgar acceso a los miembros internos del ensamblaje al conjunto de prueba de la unidad.
Aquí hay un enlace con información útil adicional y un recorrido por:
Para responder realmente a su pregunta ... Interna y protegida no se reconocen en .NET Reflection API. Aquí hay una cita de MSDN :
Las palabras clave C # protegidas e internas no tienen significado en IL y no se usan en las API de Reflection. Los términos correspondientes en IL son Familia y Asamblea. Para identificar un método interno usando Reflection, use la propiedad IsAssembly . Para identificar un método interno protegido, use IsFamilyOrAssembly .