需要:.NET中的文件系统接口和实现

Ron*_*ein 12 .net file-io unit-testing dependency-injection mocking

可能重复:
如何在C#中模拟文件系统进行单元测试?

我使用Moq作为模拟框架,将单元测试编写到我的代码中.
我的代码包括使用对System.IO类的直接调用来调用文件系统.例如,File.Exists(...)等等.
我想将该代码更改为更易测试,所以我应该有一个接口,比方说IFile,用相关的方法Exists(string path).
我知道我可以从头开始编写它,但我认为可能有一个完整,健壮的框架,它具有文件系统的接口和实现.这个(期望的)框架也可以是某种"服务",因此它的API不必是System.IO命名空间的"接口等价物" .
请注意,我真的很想拥有接口(而不是静态方法),以便我的代码可以用于依赖注入

到目前为止我得到了什么:

还有其他建议吗?

Mau*_*fer 6

我已经为静态System.IO.FileDirectory方法编写了适配器.然后在我的课程中,我执行以下操作:

public class MyService {
  public IFile File {private get;set;}
  public MyService() {
    File = new FileImpl();
  }
  public void DoSomething() {
    File.ReadAllText("somefile");
  }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以注入一个模拟作为IFile进行测试.


Cha*_*ers 5

好吧,我没有你想要的文件系统模拟库(尽管它可能在某处并且会很酷),但这可能有所帮助.单元测试思想的"行为主义"学派提出的一个有趣的概念是"外向接口"的概念.在某些情况下,将对象调用到自身之外的整个事物中并将它们转换为接口似乎具有同样多的价值,就像在外部为方法创建接口的典型行为一样世界可以调用你的对象).

在这种情况下,您可以考虑,而不是模拟整个文件系统,为您的对象需要的外部世界的答案和服务创建一个或多个逻辑上一致的接口.这些电话只会回答你需要回答的问题......而不是决定实施.然后,您可以使用您提到的依赖注入来注入您希望进行测试的实现.你可能会使用Moq这样做,因为你熟悉它.

因此,您的"传出接口"可能有一个名为DoesFileExist()的方法.它可能接受一条路径.或者,如果您的对象试图回答存在"更高级别"的业务问题,并且查看文件是否存在仅仅是回答问题的方式,那么您的传出接口可能根本没有关于文件存在的方法.它可能是"DoIAppearToHaveAccessToTheFileServer",甚至是"IsThereAPreviouslySavedGame".

这是一些工作,但可能更好地遵循良好的单元测试原则...让你的测试对象表达它想要做的事情,并让你的单元测试它并且只测试它.只是一个想法...希望它有所帮助.