Moles 在静态构造函数中不起作用
我一直遇到 Mole 类型在静态构造函数中不起作用的问题。我创建了两个简单的示例来解释问题:
我有一个简单的实例类,如下所示:
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 类,而是调用类),Moles 将不再起作用:
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");
}
...现在 Moles 不再起作用。运行此测试时,我收到错误“找不到文件 'd:\blah\blah\test.txt'”。我之所以得到这个,是因为 Moles 不再负责我的 FileSystem 类,因此单元测试正在调用原始实现,该实现正在文件系统上查找文件。
因此,唯一的变化是调用 Moled 方法的类现在是静态的。我没有更改Moled类或方法,它们仍然是实例类型,所以我无法使用Implementation.Moles.SFileSystem 语法,因为这将用于模拟静态类。
请有人帮助解释我如何让 Moles 在静态方法/构造函数中工作?
非常感谢!
I have been having a problem with Mole types not working in static constructors. I have created two simple examples to explain the problem:
I have a simple instance class as follows:
public class InstanceTestReader
{
public InstanceTestReader ()
{
IFileSystem fileSystem = new FileSystem();
this.Content = fileSystem.ReadAllText("test.txt");
}
public string Content { get; private set; }
}
I have a unit test for this as follows:
[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");
}
This works with no problems.
If I change my calling class to be static however (NOT the Moled class, but the calling class), Moles no longer works:
public static class StaticTestReader
{
static StaticTestReader ()
{
IFileSystem fileSystem = new FileSystem();
Content = fileSystem.ReadAllText("test.txt");
}
public static string Content { get; private set; }
}
And modify my unit test accordingly:
[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");
}
... Now Moles no longer works. When running this test, I get the error "Could not find file 'd:\blah\blah\test.txt'". I get this because Moles is no longer in charge of my FileSystem class, so the unit test is calling the original implementation which is looking for a file on the file system.
So, the only change is that the class which the Moled method is called from is now static. I have not changed the Moled class or method, they are still instance types, so I cannot use the Implementation.Moles.SFileSystem
syntax as this would be for mocking a static class.
Please could someone help to explain how I can get Moles to work within a static method/constructor?
Many thanks!!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
静态构造函数与静态方法不同。使用方法,您可以控制调用它的时间和地点。在执行对类的任何访问之前,运行时会自动调用构造函数,在这种情况下,会导致在设置
FileSystem
的摩尔之前调用构造函数,从而导致您看到的错误。如果您将实现更改为如下所示,那么它应该可以工作。
Update:
但是,如果您无法更改实现,Moles 提供的唯一其他替代方案是阻止执行静态构造函数中的代码,然后直接摩尔
Content
属性。要删除类型的静态构造函数,您需要在测试程序集中包含以下程序集级别属性:A static constructor is different than a static method. With a method you have control of when and where its called. The constructor is automatically called by the runtime before any access to the class is performed which in this case leads to the constructor being called before the mole for the
FileSystem
is set up resulting in the error you are seeing.If you change your implementation to something like the following then it should work.
Update:
However, if you cannot change your implementation the only other alternative that Moles offers is for you to prevent the code in the static constructor to be executed and then mole the
Content
property directly. To erase a static constructor for a type you need to include the following assembly level attribute in your test assembly:我认为您必须从声明中删除 AllInstances 。要访问静态,您不需要类的实例。
试试这个:
I think you have to remove the AllInstances from your declaration. To access the static you do not need an instance of a class.
try this: