2011-02-27 40 views
1

我写了一个简单的类来管理业务对象。如何对文件管理器类进行单元测试?

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

它将对象序列化/反序列化为本地磁盘上的文件。我为班级编写了单元测试并运行它们。到目前为止,这很好。当我的测试在构建服务器上运行时,由于文件访问权限,我不能在服务器上写入文件,所以发生问题。很明显,我不能那样测试。

我想如何单元测试这个。我可以看到的一种方法是提取一个界面并创建一个模拟对象进行测试。但我想要测试课程本身。我该怎么做?

+0

Ofc测试系统如何在真实条件下工作是有意义的,但这不是所谓的单元测试 - 它是集成测试或系统测试。这些必须有一些特殊的环境准备。 – driushkin 2011-02-27 14:57:33

+0

@driushkin是的。你是对的。但我很好奇通过单元测试混淆它)) – Arseny 2011-02-28 13:48:39

回答

5

类大概调用文件系统操作File.OpenRead()File.OpenWrite()等(我认为这是C#,由于骆驼外壳)。然后,你可以为那些操作的接口,如:

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

并使Manager的构造函数采用IFileSystem的实例。然后,通过调用实际的File.OpenRead()File.OpenWrite()方法编写实现IFileSystem的(非模拟)类,并在生产代码中使用该类。在测试中,您使用@Digger提到的模拟框架(我的个人偏好是Moq,但我没有试过Rhino Mocks,所以我没有什么不好的说法)模拟出IFileSystem并使用模拟验证是否使用正确的序列化数据调用了方法。

编辑:每请求,NUnit的有起订量为例(我没有一个IDE这里,所以它是未经检验,随时纠正它):

[Test] 
public void BObjectShouldBeSerializedToFile() { 
    var fileSystemMock = new Mock<IFileSystem>(); 
    var stream = new MemoryStream(); 
    fileSystemMock.Setup(f => f.OpenWrite("theFileNameYouExpect.txt")).Returns(new StreamWriter(stream)).Verifiable(); 
    var manager = new Manager(fileSystemMock.Object); 

    manager.SaveObject(new BObject(...)); 

    stream.Seek(0, SeekOrigin.Begin); 
    Assert.That(...); // Perform asserts on the stream contents here 
    fileSystemMock.Verify(); // Not really necessary, but verify that `OpenWrite` was called 
} 
+0

您的意思是在单元测试时验证StreamReader的内容? Moq(犀牛)能做到吗?你能提供一个简单的例子吗? – Arseny 2011-02-27 15:47:52

2

这取决于太多的逻辑是怎么包含在你的课堂上,在我看来。

如果管理器内部存在一些复杂的逻辑,按照Aasmund的建议抽象文件操作是有意义的,以便逻辑可以独立于文件系统进行测试。当有些事情足够挑剔以保证额外的依赖时,我会这样做。另一方面,如果除了调用你的序列化/反序列化代码外,如果没有其他逻辑,那么跳过单元测试并运行测试整个周期的集成测试是可以接受的(在内存中创建一个BObject,持久化它通过调用SaveObject,使用GetObject将其重新读出来,确保它与首先坚持的那个相等/相等。

如果您的构建环境无法运行集成测试,那么我会考虑设置它,这样才有可能。

相关问题