C#:如何TDD文件下载器

时间:2009-12-08 07:30:26

标签: c# tdd download

我想创建一个简单的下载工具。给它一个url列表,一个目标目录并点击go。然后它会下载这些文件并将它们转储到目标目录中。很简单。

但是,我也想练习TDD。但是你会如何在这样的应用程序中进行TDD?我可以看到应用程序的4个主要部分:

  • 下载任务(网址+目标名称,等等)
  • 下载文件的内容
  • 将文件写入磁盘的东西
  • 用户界面

无法真正TDD用户界面。下载和编写很可能是由普通的.net类完成的。刚离开下载任务,这是一个愚蠢的容器,对TDD来说不是很有趣......

你会如何TDD这样的申请?或者这是一种TDD没有意义的应用程序?

指针需要。不知道如何或从哪里开始:p

3 个答案:

答案 0 :(得分:4)

如果将逻辑从用户界面中分离出来,则可以使用TDD用户界面繁重的应用程序。简而言之,这就是MVC。这是表达为类图的一种概念性方法(省略了模型):

+----------------------+ 1
|     MyDownloadUI     +--------------+
+----------+-----------+              |
           |                          |
           | implements               |
           v                          |
+----------------------+              | 1
|     {interface}      |1   1+--------+------------+
|     DownloadView     +-----+  DownloadController |
+----------------------+     +---------------------+

您在用户界面上唯一需要做的就是实现DownloadView接口,并在DownloadController上引用它应该向其发送动作的位置。每当需要操作UI(更具体地说是视图)时,DownloadController应该只引用DownloadView接口。构造函数应该看起来像这样:

//Sample of MyDownloadUI

DownloadController controller;

public MyDownloadUI {
    this.controller = new DownloadController(this);
    //...
}

//Sample of DownloadController

DownloadView view;

public DownloadController(DownloadView view) {
    this.view = view;
    //...
}

这样,可以在没有控制器的情况下更改UI,无需担心视图的外观或所有标签和列表的名称。

这样做的好处是,您可以在下载控制器中使用TDD逻辑并使用模拟替换UI。

为了测试实际的UI,你本身并没有真正进行单元测试,它将更像是一个功能测试,因为MyDownloadUI与DownloadController紧密结合(除非你为DownloadController创建一个接口)。对于像这样的小项目,只要你更改UI或将新的东西连接到控制器,你几乎可以做手动烟雾测试。

每当你觉得一个类开始变得过多时,你总是可以选择将逻辑分解为另一个类(这使TDD变得更容易)。你已经给出了例子,例如DownloadTask,这显然是一个模范类,所以这是一个好的开始。然后,您有FileDownloaderDownloadedFile发送到FileWriter

我能想到的最简单的DownloadController实现只是一种方法:

    MyDownloadUI在想要开始下载时调用的
  • goDownload(List<string> urls)

另一个是:

  • addUrl(string url)将一个网址添加到downloadcontroller的内部列表
  • clearUrls()删除内部列表中的所有网址
  • goDownload()获取网址列表并启动“下载过程”

有很多TDD教程,我最喜欢的是dnrTV上与Jean Paul Boodhoo合作的视频(Part 1Part 2)。有很多东西需要考虑,但它在实践中表明了很多方法。

答案 1 :(得分:2)

你从更明显的开始。

我想在您的用户界面后面,您将拥有一个主控制器,其方法看起来像addFilePath()hitGo()。你必须:

  1. 嘲笑互联网。测试是你想要经常运行的东西。你不希望他们每次都下载这些东西。因此,您将模拟它以返回将成为测试套件一部分的测试文件。
  2. 致电addFilePath()
  3. 致电hitGo()
  4. 等待你的线程完成他们的工作。
  5. 测试您的整个测试文件是否已放置在正确的位置(应该是一个自动清理的临时位置,您不希望测试污染您的开发计算机)。
  6. 您还可以测试已正确调用模拟方法。
  7. 在寻找TDD的起点时,您不必看得太远。如果这样做,可能意味着甚至不知道你的应用程序应该做什么。

    编写第一个测试后,会有更多案例出现给您,允许您编写更多测试。

答案 2 :(得分:0)

当然你可以先写一下测试:)。

  • 使用每个新组件/功能 发展问问自己这是什么 功能假设要做,看看你 可以查看一些最终结果。
  • 使用模拟 - 伪造外部 依赖关系(即将文件保存到磁盘) 使用StreamWriter)。
  • 当所有事情都失败时,你总能做到 编写集成测试 - 例如 当你打电话给班级时检查一下 从特定的文件下载文件 将文件保存到磁盘。