Hacer que el código sea interno pero esté disponible para pruebas unitarias de otros proyectos


Ponemos todas nuestras pruebas unitarias en sus propios proyectos. Encontramos que tenemos que hacer ciertas clases públicas en lugar de internas solo para las pruebas unitarias. ¿Hay de todos modos para evitar tener que hacer esto. ¿Cuál es la implicación de la memoria al hacer que las clases sean públicas en lugar de selladas?

Author: leora, 2008-09-20

4 answers

Si está utilizando.NET, el atributo assembly InternalsVisibleTo le permite crear ensamblados "amigos". Estos son ensamblados específicos fuertemente nombrados que tienen permitido acceder a clases internas y miembros de la otra asamblea.

Tenga en cuenta que esto debe usarse con discreción, ya que acopla estrechamente las asambleas involucradas. Un uso común de InternalsVisibleTo es para proyectos de pruebas unitarias. Probablemente no es una buena opción para su uso en sus ensamblajes de aplicaciones reales, para la razón indicada anteriormente.

Ejemplo:

[assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{
 171
Author: Ash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-16 13:57:02

Si es una clase interna, entonces no debe estar acostumbrándose de forma aislada. Por lo tanto, realmente no debería estar probando aparte de probar alguna otra clase que hace uso de ese objeto internamente.

Así como no deberías probar miembros privados de una clase, no deberías probar clases internas de una DLL. Esas clases son detalles de implementación de alguna clase de acceso público y, por lo tanto, deben ejercerse bien a través de otras pruebas unitarias.

La idea es que usted solo desea probar el comportamiento de una clase porque si prueba los detalles de la implementación interna, sus pruebas serán frágiles. Debería poder cambiar los detalles de implementación de cualquier clase sin romper todas sus pruebas.

Si usted encuentra que realmente necesita probar esa clase, entonces es posible que desee reexaminar por qué esa clase es interna en primer lugar.

 5
Author: Josh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 03:22:53

A efectos de documentación

Alternativamente, puede crear una instancia de clase interna mediante el métodoType.GetType

Ejemplo

//IServiceWrapper is public class which is 
//the same assembly with the internal class 
var asm = typeof(IServiceWrapper).Assembly;
//Namespace.ServiceWrapper is internal
var type = asm.GetType("Namespace.ServiceWrapper");
return (IServiceWrapper<T>)Activator
    .CreateInstance(type, new object[1] { /*constructor parameter*/ });

Para el tipo genérico hay diferentes procesos como abajo:

var asm = typeof(IServiceWrapper).Assembly;
//note the name Namespace.ServiceWrapper`1
//this is for calling Namespace.ServiceWrapper<>
var type = asm.GetType("Namespace.ServiceWrapper`1");
var genType = type.MakeGenericType(new Type[1] { typeof(T) });
return (IServiceWrapper<T>)Activator
     .CreateInstance(genType, new object[1] { /*constructor parameter*/});
 3
Author: ktutnik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-23 05:45:50

Las clases pueden ser públicas Y selladas.

Pero, no hagas eso.

Puede crear una herramienta para reflejar sobre las clases internas, y emitir una nueva clase que accede a todo a través de la reflexión. MSTest hace eso.

Edit: Quiero decir, si no quieres incluir ninguna prueba en tu ensamblado original; esto también funciona si los miembros son privados.

 -2
Author: TraumaPony,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-22 03:30:47