Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要:文件系统接口和.NET中的实现_.net_Unit Testing_File Io_Dependency Injection_Mocking - Fatal编程技术网

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

需要:文件系统接口和.NET中的实现,.net,unit-testing,file-io,dependency-injection,mocking,.net,Unit Testing,File Io,Dependency Injection,Mocking,可能重复: 我使用Moq作为模拟框架,在代码中编写单元测试。 我的代码包括对文件系统的调用,使用对system.IO类的直接调用。例如,File.Exists(…)等 我想将该代码更改为更易于测试的代码,因此我应该有一个接口,比如说IFile,以及一个相关的方法,比如说Exists(string path) 我知道我可以从头开始编写它,但我认为可能有一个完整、健壮的框架,它同时具有文件系统的接口和实现。这个(期望的)框架也可能是某种“服务”,因此它的API不必是System.IO名称空间的“等

可能重复:

我使用Moq作为模拟框架,在代码中编写单元测试。
我的代码包括对文件系统的调用,使用对
system.IO
类的直接调用。例如,
File.Exists(…)

我想将该代码更改为更易于测试的代码,因此我应该有一个接口,比如说
IFile
,以及一个相关的方法,比如说
Exists(string path)

我知道我可以从头开始编写它,但我认为可能有一个完整、健壮的框架,它同时具有文件系统的接口和实现。这个(期望的)框架也可能是某种“服务”,因此它的API不必是
System.IO
名称空间的“等价接口”。
请注意,我确实希望有接口(和而不是静态方法),这样我的代码就可以进行依赖注入了

到目前为止,我得到的是:
  • 在stackoverflow中,有人问了一个类似的问题
  • 在中,有一个名为CodePlex Source Control Client()的项目,它在源代码中有这样的类(有关具体细节,请参阅源代码中的
    /Source/TfsLibrary/Utility/

还有其他建议吗?

我知道软件包可以做类似的事情。

我传统上选择模拟文件系统接口,而不是模拟文件系统本身。在任何严肃的操作系统上,这都是一项相对容易的任务。通过用户空间中的文件系统的C#实现,您可以非常轻松地构建用户空间文件系统。我不确定是否需要进行任何移植,FUSE for Windows,但FUSE在Linux、OSX和Solaris上运行良好。

好的,我没有您想要的文件系统模拟库(尽管它可能在某处,而且很酷),但这可能会有所帮助。单元测试思想的“行为主义”学派提出的一个有趣的概念是“外向接口”的概念。在某些情况下,将一个对象对其自身以外的整个宇宙的调用,并将其转化为一个接口,似乎有着与为外部世界可以对您的对象调用的方法创建接口的典型行为一样的价值

在这种情况下,您可能会考虑,而不是嘲笑整个文件系统,为您的对象从外部世界提供的答案和服务提供一个或多个逻辑上一致的接口。这些电话只会回答你需要回答的问题。。。不要求执行。然后,您可以使用您提到的依赖项注入来注入您希望用于测试的实现。你可能会用最小起订量来做,因为你很熟悉它

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

这是一些工作,但可能更符合良好单元测试的原则。。。让您的测试对象表达它试图做什么,让您的单元测试测试它,并且只测试它。只是一个想法。。。希望对您有所帮助。

对于静态
System.IO.File
目录
方法。然后在我的课堂上,我做了以下几点:

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

然后您可以插入一个模拟文件进行测试。

我在CodePlex上维护该项目,该项目包含一个库来为您生成此类接口及其实现。更多信息请参考图书馆。

提供了一个不错的选择,尽管我还没有尝试过。看来作者需要一些帮助才能完成这个项目。

真的吗?你真的试过吗?上次我看了一下Windows上的保险丝,它一点也不成熟。老实说,如果我们在模拟文件系统,我认为这是把整个TDD事情做得太过分了。“如果我们在模拟文件系统,我认为这是把整个TDD事情做得太过分了。”-宾果。或者你需要一种自我毁灭的嗜好来开始这个永无止境的任务。这种东西不是也被称为“访问者模式”吗?但是,当我实现“传出接口”时,我必须与文件系统交互。例如,实现“IsThereAppReviousLysavedName”方法实际上可能会检查特定文件是否存在。所以我仍然需要IFile接口,这样我就可以正确地对实现进行单元测试。不,等等。我的意思是,“IsthereaPreviouslySavedName”将是一个布尔方法。你的代码会调用它。对于单元测试,您只需“注入”一个返回true的模拟实现,并确保生成的行为在这种情况下是正确的。不需要文件系统。(继续)。。。这样,您的单元测试将严格关注您正在测试的单个对象。查看Martin Fowler的文章,了解更多关于这一理念的信息。我个人认为这个想法是有价值的,但我并不虔诚地使用它。有些情况需要这样做,有些则不然。(更多…(继续)。。。这里是链接:关注他所谓的“嘲笑者”的观点。这正是我需要的,谢谢!blogpost中的链接似乎已经不存在了。我就是为了这个目的写的(还有更多),它仍然是WIP,API肯定会改变,但它已经工作了,并且包含了一些测试。