如果我要编写用于读/写/创建注册表项或文件的单元测试,我的理解是我不应该使用真正的注册表和文件系统,而应该以轻量级的方式模拟它们。
您建议在C#desktop / WPF样式应用程序中使用哪些模拟框架进行模拟? 什么是一个很好的介绍性阅读这个主题?
答案 0 :(得分:2)
好的,这是一个例子。
鉴于这些课程:
public interface IRegistryActions
{
bool WriteValue(string key, string value);
}
public class RegistryActions : IRegistryActions
{
public bool WriteValue(string key, string value)
{
// pseudocode
// var key = Registry.OpenKey(key);
// Registry.WriteValue(key, value);
}
}
这个使用它们的类:在这个例子中,将执行动作的类传递给构造函数,但可以很容易地成为属性。这意味着无论何时您想在实际代码中实际使用该类,您都可以显式传递实现IRegistryActions
的类作为参数 - 例如var exampleClass = new ExampleClass(new RegistryActions());
- 或者如果传递为null,则默认为实际实现,即this.registryActions = registryActions ?? new RegistryActions();
public class ExampleClass
{
private IRegistryActions registryActions;
public ExampleClass(IRegistryActions registryActions)
{
this.registryActions = registryActions;
}
public bool WriteValue(string key, string value)
{
return registryActions.WriteValue(key, value);
}
}
因此,在您的单元测试中,您需要验证是否使用正确的参数进行了调用。你究竟是如何做到这一点取决于你使用的模拟框架,这通常是个人选择的问题,或者你使用已经使用过的东西。
[Test]
public void Test_Registry_Writes_Correct_Values()
{
string key = "foo";
string value = "bar";
// you would normally do this next bit in the Setup method or test class constructor rather than in the test itself
Mock<IRegistryActions> mock = MockFramework.CreateMock<IRegistryActions>();
var classToTest = new ExampleClass(mock); // some frameworks make you pass mock.Object
// Tell the mock what you expect to happen to it
mock.Expect(m => m.WriteValue(key, value));
// Call the action:
classToTest.WriteValue(key, value);
// Check the mock to make sure it happened:
mock.VerifyAll();
}
在此,您断言您的类已在接口上调用了正确的方法,并传递了正确的值。