代码之家  ›  专栏  ›  技术社区  ›  rodbv

TDD:你会如何处理这个类,测试第一样式?

  •  4
  • rodbv  · 技术社区  · 17 年前

    我正在编写一个小应用程序来自学ASP.NET MVC,它的一个特点是能够在亚马逊(或其他网站)上搜索书籍并将其添加到“书架”中。

    所以我创建了一个名为ibooksearch的接口(使用dosearch方法),以及一个类似这样的实现amazonsearch

    public class AmazonSearch : IBookSearch
    {
       public IEnumerable<Book> DoSearch(string searchTerms)
       {  
          var amazonResults = GetAmazonResults(searchTerms);
          XNamespace ns = "http://webservices.amazon.com/AWSECommerceService/2005-10-05";
          var books= from item in amazonResults.Elements(ns + "Items").Elements(ns + "Item")
                     select new Book
                     {
                          ASIN = GetValue(ns, item, "ASIN"),
                          Title = GetValue(ns, item, "Title"),
                          Author = GetValue(ns, item, "Author"),
                          DetailURL = GetValue(ns, item, "DetailPageURL")
                     };
          return books.ToList();
      }
    
      private static XElement GetAmazonResults(string searchTerms)
      { 
          const string AWSKey = "MY AWS KEY";
          string encodedTerms = HttpUtility.UrlPathEncode(searchTerms);
          string url = string.Format("<AMAZONSEARCHURL>{0}{1}",AWSKey, encodedTerms);
          return XElement.Load(url);
      }
    
      private static string GetValue(XNamespace ns, XElement item, string elementName)
      {
         //Get values inside an XElement
      }
    
    }
    

    理想情况下,我想做这个TDD风格,首先写一个测试和所有。但我得承认我很难理解。

    我可以创建一个实现dosearch()的fakesearch,并返回一些特别的书籍,但我认为这目前没有任何价值,是吗?也许稍后当我有一些代码使用书籍列表时。

    我还可以先测试什么?我能想到的唯一测试是模拟对云的调用(在getamazonresults),然后检查dosearch是否可以正确执行linq2xml select并返回正确的列表。但在我看来,这种类型的测试只有在我有了一些代码之后才能编写,所以我知道 什么 嘲弄

    有什么关于你们如何在第一种风格的测试中四处走动的建议吗?

    3 回复  |  直到 15 年前
        1
  •  3
  •   MattK    17 年前

    您在这里的主要问题似乎是知道何时编写模拟代码。我明白你的意思:如果你还没有写代码,你怎么能嘲笑它呢?

    我认为答案是你想用非常简单的测试开始你的TDD,就像肯特·贝克在 Test Driven Development . 首先编写一个调用dosearch并断言接收到的不是空的测试,然后编写一些代码使其通过。然后编写一个测试,断言您正在为一个已知的搜索词检索适当数量的图书,并编写代码使其通过。最终,您将到达一个需要接收实际、有效图书数据以通过测试的点,此时,您将编写一部分Dosearch,并且可以考虑模拟它(或其中的一部分)。

        2
  •  2
  •   Allain Lalonde    17 年前

    当您测试使用搜索的代码时,您将希望编写一个模拟,而不是测试搜索本身。

    对于上述课程,我可以通过以下方式进行测试:

    • 正在搜索一本普通书籍并检查是否找到并有效。
    • 搜索随机固定字符串“kjfdskajfkldsajklfjafa”,确保没有找到任何书籍
    • 等

    但是…这里有一个大的,我从来没有模拟出我正在测试的一个类,我会模拟出它使用的类。

    长话短说:当测试用户界面在按下搜索按钮时是否正常工作时,将使用fakesearch。我可以确保它被调用,并且UI正确地处理返回的图书。

    希望有帮助。

        3
  •  0
  •   Esko Luontola    15 年前

    在这个类中,主要的焦点似乎是它与Amazon的Web服务正确集成。因为那个Web服务不是你自己的,所以你不应该嘲笑它,因为你对它的工作方式不太了解。 "Only mock types you own" , "don't mock third-party libraries" 等。

    以下是解决问题的一些方法:

    编写一个连接到 真实的 网络上的Web服务 或许在未来的几年里,你会一直在寻找一本非常受欢迎的书。这可以很好地保证您正确地使用服务,但它也会受到许多误报的影响-例如,有时网络可能会关闭,或者远程系统中的数据会发生变化。所以你也需要一些测试…

    针对静态数据文件写入测试 ,它基于来自真实Web服务的数据。要获取测试数据,可以手动对Web服务执行请求,并将响应写入文件*。您需要模拟网络连接(或者使用一个不联网的存根,或者在测试中启动一个嵌入式Web服务器并连接到它,而不是真正的URL)。通过这种方式,您可以轻松地测试各种角情况和错误情况,并且无论真实的Web服务发生了什么,数据都将始终可用并保持不变。一个警告是,如果真实Web服务的API发生变化,这些测试将不会注意到它,因此您还需要针对真实Web服务编写一些测试(如上所述)。

    *例如,有一次我使用cron和一个shell脚本每隔几分钟从一个包含不断变化的日程信息的Web服务下载一次数据。在几周内收集这样的数据作为测试数据非常有用。从这些数据中,我手工制作了静态响应,其中包含了我在实际数据中注意到的各种特殊情况。它还可以用来设置一个假Web服务和一个“时间机器”,重放先前捕获的数据,这样我们的系统就可以在没有访问真实Web服务的情况下使用。