TDD - 如何在没有.Write()的情况下测试.Read()?

时间:2015-07-11 00:16:49

标签: unit-testing testing tdd

我们正在尝试使用TDD来创建我们的系统,而且我们已经找到了能够找出正确的TDD行动方案的情况。

我们已将文件IO隐藏在接口之后,如下所示:

public interface IFileIo
{
    byte[] Read(string fileName);
    void Write(string filename, byte[] data);
}

现在我们正在创建一个InMemoryFileIo,我们可以用它来代替我们用于制作的真实SystemFileIo类。

我们希望确保此InMemoryFileIo正常工作,并且可能存在我们想要使用它来代替实际文件系统的情况,因此它应该是&#34;生产质量&#34;。< / p>

问题是,按照TDD方式执行所有操作&#34;,我们如何为.Read().Write()创建测试,他们不依赖于每个.Read().Write()其他

为了测试.Write()是否正常工作,我们首先需要成功调用.Read(),同样地,测试.Read()是否正常工作,我们需要之后致电.Write()。通过这样做,我们实际上创建了两次相同的测试(排列,然后写入,然后读取,然后断言)。

假设我们有两个测试,一个测试put,另一个测试get。如果这些功能中的任何一个不起作用,那么两个测试都会失败。这违反了&#34;测试应该只有一个失败的理由&#34;

此处的示例适用于文件IO,但在使用数据库时我们遇到了同样的问题(测试(index) Width Height Scale Name 0 640 360 1 "SD" 1 1080 720 2 "HD" 2 1920 1080 3 "FHD" 没有struct Resolution { int Width; int Height; int Scale; std::string Name; }; )。

1 个答案:

答案 0 :(得分:2)

整个问题归结为你如何定义你的&#34;单位&#34;。就我个人而言,有必要考虑一个&#34;单位&#34;作为一个连贯的行为集而不是单个方法调用。

Roy Osherove将单位定义为:

  

单元测试是一段自动化的代码,它调用系统中的一个工作单元,然后检查有关该工作单元行为的单一假设。工作单元是系统中的单个逻辑功能用例,可以由某个公共接口调用(在大多数情况下)。工作单元可以跨越单个方法,整个类或多个类一起工作,以实现可以验证的单个逻辑目的。

所以最后,抛开所有指导方针,如果分开阅读/写作责任没有意义,只需要组合测试它们。一般来说,当我觉得没有干净/简单的方法可以通过后门验证测试结果时(无论是可以嘲笑的合作者,还是一些状态验证,......),我可以毫无问题地进行一些操作。公共API的其他功能。这些通过公共API运行组件的测试往往不如使用后门进行验证的那些脆弱。