如何单元测试文件管理器类?

时间:2011-02-27 14:30:24

标签: unit-testing tdd nunit

我写了一个简单的类来管理业务对象。

class Manager
{ 
 string[] GetNames();
 BObject GetObject(string name);
 void Saveobject(BObject obj);
}

它将对象序列化/反序列化为本地磁盘上的文件。我为类编写了单元测试并运行它们。到目前为止这很好。由于文件访问权限,我的测试在构建服务器上运行时会出现问题我不允许在服务器上写文件。很明显我无法测试那种方式。

我想如何对此进行单元测试。我能看到的一种方法是提取一个接口并创建一个模拟对象进行测试。但我想测试这个类本身。我该怎么办?

2 个答案:

答案 0 :(得分:5)

该类可能调用文件系统操作File.OpenRead()File.OpenWrite()等(我认为这是C#,因为骆驼套管。)然后,您可以为这些操作创建一个接口,例如:

public interface IFileSystem {
    StreamReader OpenRead(string fileName);
    StreamWriter OpenWrite(string fileName);
}

并使Manager的构造函数采用IFileSystem的实例。然后,通过调用实际的IFileSystemFile.OpenRead()方法编写实现File.OpenWrite()的(非模拟)类,并在生产代码中使用此方法。在测试中,你使用了一个模拟框架,正如@Digger所提到的(我的个人偏好是Moq,但我没有尝试过Rhino Mocks,所以我没有任何消极的说法)来模拟{{ 1}}并使用mock来验证是否使用正确的序列化数据调用了方法。

编辑:每个请求,在NUnit中使用Moq的一个示例(我这里没有IDE,所以它没有经过测试;随意纠正它):

IFileSystem

答案 1 :(得分:2)

在我看来,这取决于你班级中包含多少逻辑。

如果您的经理内部存在一些复杂的逻辑,那么根据Aasmund的建议抽象您的文件操作是有意义的,这样逻辑就可以独立于文件系统进行测试。当有些东西足够严格以保证额外的依赖性时,我会这样做。

另一方面,如果除了调用序列化/反序列化代码之外几乎没有逻辑,那么跳过单元测试并运行测试整个周期的集成测试通常是可以接受的(创建BObject in记忆,通过调用SaveObject保留,使用GetObject将其读回来,确保它与您在第一时间保持的等同/等效。)

如果你的构建环境无法运行集成测试,那么我会考虑设置它以便它可以。