我们有一些方法调用 File.Copy、File.Delete、File.Exists 等。我们如何在不实际访问文件系统的情况下测试这些方法?
我认为自己是一个单元测试 n00b,所以任何建议都值得赞赏。
我们有一些方法调用 File.Copy、File.Delete、File.Exists 等。我们如何在不实际访问文件系统的情况下测试这些方法?
我认为自己是一个单元测试 n00b,所以任何建议都值得赞赏。
public interface IFile {
void Copy(string source, string dest);
void Delete(string fn);
bool Exists(string fn);
}
public class FileImpl : IFile {
public virtual void Copy(string source, string dest) { File.Copy(source, dest); }
public virtual void Delete(string fn) { File.Delete(fn); }
public virtual bool Exists(string fn) { return File.Exists(fn); }
}
[Test]
public void TestMySystemCalls() {
var filesystem = new Moq.Mock<IFile>();
var obj = new ClassUnderTest(filesystem);
filesystem.Expect(fs => fs.Exists("MyFile.txt")).Return(true);
obj.CheckIfFileExists(); // doesn't hit the underlying filesystem!!!
}
如果您绝对必须这样做,Typemock Isolator是您的朋友。
我不能说我自己使用过它,我会尝试围绕它设计自己的方式,但据我所知,它会完成这项工作。
我会为此使用起订量。您必须创建一个接口和一个代理到真实事物的类,这样您就可以让 Moq 创建您的代理实例(一个模拟实例),但它是测试这类事物的最佳方式。
您可以为此使用模拟框架,它将创建 File 对象的假副本,您可以将文件注入到被测系统中。
我会推荐Rhino Mock。
我倾向于在我的大多数项目中创建一个名为 IFileController 的接口,其中包含所有文件操作。这可以包含基本的方法,以及 .NET 框架未提供的处理文件的任何方法。
使用依赖注入框架,您可以获得 IFileController 的实例,而无需确切知道它是什么类型,并使用它而不需要弄乱模拟框架类型。这使得一切都更加可测试,并且作为奖励,您可以更改文件存储机制,而无需更改您的代码。
不利的一面是,需要告知任何新开发人员有关此接口的信息,否则他们将直接使用 .NET 方法。
我在 CodePlex 上维护Jolt.NET项目,其中包含一个库,可以为您生成此类接口及其实现。有关更多信息,请参阅Jolt.Testing库。