2011-07-01 31 views
1

我一直有一个问题,痣类型不工作在静态构造函数。我已经创建了两个简单的例子来说明这个问题:痣不能在静态构造函数中工作

我有一个简单的实例类如下:

public class InstanceTestReader 
{ 
    public InstanceTestReader() 
    { 
     IFileSystem fileSystem = new FileSystem(); 

     this.Content = fileSystem.ReadAllText("test.txt"); 
    } 

    public string Content { get; private set; } 
} 

我有一个单元测试的具体步骤如下:

[TestMethod] 
    [HostType("Moles")] 
    public void CheckValidFileInstance_WithMoles() 
    { 
     // Arrange 
     string expectedFileName = "test.txt"; 
     string content = "test text content"; 

     Implementation.Moles.MFileSystem.AllInstances.ReadAllTextString = (moledTarget, suppliedFilename) => 
     { 
      Assert.AreEqual(suppliedFilename, expectedFileName, "The filename was incorrect"); 
      return content; 
     }; 

     // Act 
     string result = new InstanceTestReader().Content; 

     // Assert 
     Assert.AreEqual(content, result, "The result was incorrect"); 
    } 

该作品没有问题。

如果我改变我的呼唤类是静态但(不是Moled类,但调用的类),痣不再有效:

public static class StaticTestReader 
{ 
    static StaticTestReader() 
    { 
     IFileSystem fileSystem = new FileSystem(); 

     Content = fileSystem.ReadAllText("test.txt"); 
    } 

    public static string Content { get; private set; } 
} 

,并相应修改我的单元测试:

[TestMethod] 
    [HostType("Moles")] 
    public void CheckValidFileStatic_WithMoles() 
    { 
     // Arrange 
     string expectedFileName = "test.txt"; 
     string content = "test text content"; 

     Implementation.Moles.MFileSystem.AllInstances.ReadAllTextString = (moledTarget, suppliedFilename) => 
     { 
      Assert.AreEqual(suppliedFilename, expectedFileName, "The filename was incorrect"); 
      return content; 
     }; 

     // Act 
     string result = StaticTestReader.Content; 

     // Assert 
     Assert.AreEqual(content, result, "The result was incorrect"); 
    } 

...现在痣不再有效。运行此测试时,出现错误“无法找到文件”d:\ blah \ blah \ test.txt'“。我得到这个是因为Moles不再负责我的FileSystem类,所以单元测试正在调用正在文件系统上寻找文件的原始实现。

所以,唯一的变化就是Moled方法被调用的类现在是静态的。我没有更改Moled类或方法,它们仍然是实例类型,所以我不能使用Implementation.Moles.SFileSystem 语法,因为这将用于模拟静态类。

请有人可以帮助解释如何让痣在静态方法/构造函数中工作?

非常感谢!

回答

4

静态构造函数与静态方法不同。通过一种方法,您可以控制其何时何地被调用。在执行任何对类的访问之前,构造函数会被运行时自动调用,在这种情况下会导致构造函数在设置FileSystem的痣之前被调用,从而导致出现错误。

如果你改变你的实现类似于下面的东西,那么它应该工作。

public static class StaticTestReader 
{ 
    private static string content; 

    public static string Content 
    { 
     get 
     { 
      if (content == null) 
      { 
       IFileSystem fileSystem = new FileSystem(); 

       content = fileSystem.ReadAllText("test.txt"); 
      } 

      return content; 
     } 
    } 
} 


更新:

但是,如果你不能改变你的实现是痣提供唯一的其他选择是为你避免被执行的静态构造函数的代码,然后痣Content直接属性。要删除一个静态构造函数,你需要包含以下组件级属性在您的测试程序集的类型:

[assembly: MolesEraseStaticConstructor(typeof(StaticTestReader))] 
+0

+1写得很好的解释! – TheSilverBullet

0

我认为你必须从你的声明中删除AllInstances。要访问静态,你不需要一个类的实例。

试试这个:

Implementation.Moles.MFileSystem.ReadAllTextString = (...)