2012-07-17 24 views
21

Quiero escribir la prueba de unidad para la clase inferior.
Si el nombre es distinto de "MyEntity", el mgr debe estar en blanco.
Prueba de Unidad Negativa
Usando el acceso directo de Administrador privado Deseo cambiar el nombre a "Prueba" para que mgr sea nulo. Y luego verificará el valor de mgr. Para lograr esto, quiero llamar explícitamente al constructor estático pero cuando llamo al constructor estático utilizando el nombreLlamar explícitamente al constructor estático

Manager_Accessor.name = "Test" 
typeof(Manager).TypeInitializer.Invoke(null, null); 

siempre se establece en "myEntity" cómo configurar el nombre de "prueba" e invocar el constructor estático .

public class Manager 
{   
     private static string name= "MyEntity"; 

     private static object mgr; 

     static Manager() 
     { 
      try 
      { 
       mgr = CreateMgr(name); 
      } 
      catch (Exception ex) 
      { 
       mgr=null; 
      } 
     } 
} 
+2

Hacer '' mgr medios estáticos que todas las instancias * * 'administrador' comparten la misma * * ' valor de mgr ', que tampoco puede cambiarse nunca (ya que es de solo lectura). ¿Es eso realmente lo que quieres? –

+3

¿Necesita cambiar un valor privado estático codificado que es responsable de establecer un valor privado de lectura estática para fines de prueba? Esta es la razón por la que la mayoría de las elecciones de diseño para la capacidad de prueba no son favorables a la estática. –

Respuesta

27

Como puede observar, hoy en día, el constructor estático se puede llamar directamente:

de another Stackoverflow post

Las otras respuestas son excelentes, pero si es necesario forzar un constructor de la clase a ejecutar sin tener una referencia al tipo (es decir, reflexión ), puede utilizar:

Type type = ...; 
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle); 

Tuve que agregar este código a mi aplicación to work around a possible bug in the .net 4.0 CLR.

4

Si tiene un miembro estático en su clase (debe haber, de lo contrario, el constructor estático no haría demasiado), entonces no es necesario llamar explícitamente al constructor estático.

Simplemente acceda a la clase a la que le gustaría llamar su constructor estático. ej .:

public void MainMethod() 
{ 
    // Here you would like to call the static constructor 

    // The first access to the class forces the static constructor to be called. 
    object temp1 = MyStaticClass.AnyField; 

    // or 
    object temp2 = MyClass.AnyStaticField; 
} 
2

Para cualquier persona encontrar este hilo y preguntándose ... Acabo de hacer la prueba. Parece que System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor() solo ejecutará el constructor estático si tiene no ya se ha ejecutado por otro motivo.

Por ejemplo, si su código no es positivo, ya sea que el código anterior haya accedido o no a la clase y haya activado el constructor estático, no importa. Ese acceso previo habrá activado el constructor estático para ejecutarse, pero RunClassConstructor() tampoco lo ejecutará. RunClassConstructor() solo ejecuta el constructor estático si aún no se ha ejecutado.

Acceder a la clase después de que RunClassConstructor() también lo haga no como resultado el constructor estático se está ejecutando por segunda vez.

Esto se basa en las pruebas en una aplicación Win10 UWP.

+0

Eso me pone muy triste como ahora cada vez que quiero restablecer los valores de mi clase estática. Necesito llamar a su método estático que hace exactamente lo mismo que el constructor: establece los valores predeterminados. –

+0

Correcto. No estás "construyendo" los objetos de nuevo. Solo estableciendo sus valores. Supongamos que ya ha construido un objeto no estático y ha almacenado referencias a él en varios lugares diferentes en su código. Ahora quiere restablecer los valores del objeto. No reconstruirías ("nuevo") el objeto nuevamente. Todas esas viejas referencias almacenadas seguirían siendo para el objeto viejo. En su lugar, tendría un método que restablece los valores en el objeto ya construido. Entonces te darías cuenta de que el constructor y los métodos de reinicio estaban haciendo lo mismo, por lo que acababas de llamar al método de reinicio desde el constructor. – kburgoyne

0

Ponga el código que desea llamar en el constructor en un método público y lo llaman desde el constructor

Cuestiones relacionadas