我正在编写一个小应用程序来自学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选择并返回正确的列表。但在我看来,这种类型的测试只能在我有一些代码后编写,所以我知道要模拟的。
关于你们男孩和女孩如何做这个测试优先风格的任何建议?
答案 0 :(得分:3)
这里的主要问题似乎是知道何时编写模拟代码。我明白你的观点:如果你还没有编写代码,你怎么能嘲笑它?
我认为答案是你想用非常非常简单的测试开始你的TDD,正如Kent Beck在Test Driven Development中所做的那样。首先编写一个调用DoSearch的测试,并断言你收到的内容不是null,并编写一些代码来进行调用。然后编写一个测试,声明您正在检索已知搜索词的正确数量的书籍,并编写代码以进行该传递。最终你会得到一个点,你需要接收实际的,有效的书籍数据来通过测试,此时,你将有一部分DoSearch被写,你可以考虑嘲笑它(或者它的一部分) )。
答案 1 :(得分:2)
当您测试使用搜索的代码时,您会想要编写模拟,而不是测试搜索本身。
对于上面的课程,我可以通过以下方式进行测试:
但是..这里是最重要的一个,我永远不会嘲笑我正在测试的一个类,我会模拟它使用的类。
长话短说:当按下“搜索”按钮测试UI工作正常时,将使用FakeSearch。我可以确保它被调用,并且UI正在正确地处理退回的书籍。
希望有所帮助。
答案 2 :(得分:0)
在本课程中,主要焦点似乎是它与亚马逊的网络服务正确集成。由于该Web服务不是您拥有的,因此您不应该嘲笑它,因为您不了解它的工作原理。 "Only mock types you own","don't mock third-party libraries"等。
以下是解决问题的方法:
编写一个通过网络连接到真实网络服务的测试,也许会搜索一些非常受欢迎的图书,您可以信赖它将在未来几年内出现。这可以很好地保证您正确使用该服务,但它也会受到许多误报 - 例如,有时网络可能会关闭,或者远程系统中的数据会发生变化。因此,您还需要进行测试......
针对静态数据文件编写测试,这些测试基于来自真实Web服务的数据。要获取测试数据,您可以手动对Web服务执行请求并将响应写入文件*。您将需要模拟网络连接(使用不进行网络连接的存根,或者通过在测试中启动嵌入式Web服务器并连接到它而不是真实URL)。通过这种方式,您可以轻松地测试各种角落情况和错误情况,无论真实Web服务发生什么,数据都将始终可用并保持不变。需要注意的是,如果真实Web服务的API发生变化,这些测试将不会注意到它,因此您还需要针对真实Web服务编写一些测试(如上所述)。
*例如,一旦我使用cron和一个小的shell脚本从Web服务下载每隔几分钟的数据,其中包含不断变化的计划信息。将这些数据收集几周是非常有用的测试数据。根据这些数据,我手工制作了静态响应,其中包含我在实际数据中注意到的各种特殊情况。它对于设置假的Web服务和重放早期捕获的数据的“时间机器”也很有用,这样我们的系统就可以在不访问真实Web服务的情况下使用。