模拟注册表和文件系统

时间:2017-03-14 22:13:59

标签: c# wpf unit-testing filesystems registry

如果我要编写用于读/写/创建注册表项或文件的单元测试,我的理解是我不应该使用真正的注册表和文件系统,而应该以轻量级的方式模拟它们。

您建议在C#desktop / WPF样式应用程序中使用哪些模拟框架进行模拟? 什么是一个很好的介绍性阅读这个主题?

1 个答案:

答案 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();
}

在此,您断言您的类已在接口上调用了正确的方法,并传递了正确的值。