2012-07-17 144 views
21

我想为下面的类写单元测试。
如果名称不是“MyEntity”,那么mgr应该是空白的。
负单元测试
使用管理器专用访问器我想将名称更改为“Test”,以便mgr应该为空。 然后将验证mgr值。 要做到这一点,我想明确地调用静态构造函数 但是当我打电话使用显式调用静态构造函数

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

的名字总是被设置为“myEntity所”如何设置名称为“测试”并调用静态构造函数静态构造函数。

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

     private static object mgr; 

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

把它制作“经理”静态意味着*所有*“经理”实例共享相同的* *“的代码mgr'值,这也是永远不会被改变的(因为它是只读的)。那真的是你想要的吗? – 2012-07-17 10:46:59

+3

所以你需要改变一个私人的硬编码静态值,负责设置一个私有静态只读值用于测试目的?这就是为什么大多数可测试性的设计选择都不喜欢静态。 – 2012-07-17 10:56:13

回答

27

正如我今天发现,静态构造函数,可直接调用:

another Stackoverflow post

其他的答案是优秀的,但如果你需要强制的一类 构造函数可以使用:

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

我不得不将此代码添加到我的应用程序to work around a possible bug in the .net 4.0 CLR

4

如果您的类中有静态成员(必须存在,否则静态构造函数不会做太多),则不需要显式调用静态构造函数。

只需访问您希望调用其静态构造函数的类。 例如: -

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

对于任何人发现这个线程,不知道......我只是做了测试。看起来System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor()只会运行静态构造函数,如果它有而不是已由于其他原因而运行。

例如,如果您的代码不正确,无论先前的代码是否可能访问了类并触发了要运行的静态构造函数,则无关紧要。以前的访问会触发静态构造函数运行,但RunClassConstructor()也不会运行它。 RunClassConstructor()只运行静态构造函数,如果它尚未运行。

RunClassConstructor()也访问类而不是导致第二次运行静态构造函数。

这是基于Win10 UWP应用程序中的测试。

+0

这让我非常伤心,因为现在每当我想重置我的静态类的值时,我需要调用它的构造函数完全相同的静态方法 - 设置默认值。 – 2018-02-28 12:46:13

+0

正确。你不是再次“构建”对象。只设置它们的值。假设你已经构建了一个非静态对象,并在代码中的一堆不同的地方存储了对它的引用。现在你想重置对象的值。你不会重新构造(“新”)对象。所有那些旧的存储引用仍然是旧对象。相反,你会有一个方法来重置已经构建的对象上的值。然后你会意识到构造函数和重置方法在做同样的事情,所以你只需从构造函数调用reset方法。 – kburgoyne 2018-03-01 15:37:39

0

把你想在构造函数中调用到一个公共方法,并从构造