TDD: How will you work in this class, in a test style?

I am writing a small application to teach ASP.NET MVC, and one of its features is the ability to search for books on Amazon (or other sites) and add them to the bookshelf.

So, I created an IBookSearch interface (with DoSearch method) and an AmazonSearch implementation that looks like

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 } } 

Ideally, I would like to make this TDD style by writing a test first and thatโ€™s it. But I have to admit that I am having problems with my head.

I could create a FakeSearch that implements DoSearch () and will return some special books, but I don't think this brings any value at the moment, does it? Maybe later, when I have code that uses a list of books.

What else could I check first? The only test I can come up with is one that makes fun of a call in the cloud (in GetAmazonResults), and then checks that DoSearch can correctly execute Linq2XML and return the correct list. But it seems to me that this type of test can only be written after I have the code in place, so I know what to make fun of.

Any tips on how you guys and girls will get around this first test?

+4
source share
3 answers

It seems your main problem here is to know when to write the code layout. I see your thought: if you haven't written the code yet, how can you mock it?

I think the answer is that you want to start your TDD with very simple tests, as Kent Beck does in Test Driven Development . Start by writing a test that calls DoSearch and says that what you get is not is null and write some code to make this pass. Then write a test stating that you get the right number of books for a known search term and write down the code to go through this passage. In the end, you get to the point where you need to get the actual, valid Book data in order to pass the test, and at that moment you will have the DoSearch part written and you can think of the mockery (or parts of it)).

+3
source

You want to write a layout when you test code that uses a search, and not to test the search itself.

For the class above, I can check:

  • Search for a shared book and check that was found and valid.
  • search for a random fixed string "kfdskkfkldskajlfjafa" and ensuring that books are not found.
  • etc.

But .. and now the big one, I never scoffed at the class that I tested, I would scoff at the classes that he used.

In short: FakeSearch will be used when testing the correct functioning of the user interface when you click the Search button. I could verify that it was called, and that the user interface correctly handled the returned books.

Hope this helps.

+2
source

This class focuses on the fact that it integrates correctly with Amazon web services. Since this web service is not something that belongs to you, you should not scoff at it, because you do not have deep knowledge of how it works. "Only the layout of the types you own , " "do not mock third-party libraries," etc.

Here are some ways to approach the problem:

Write a test that connects to a real web service via the network , perhaps searching for some very popular book that you can trust will last for many years. This gives you good confidence that you are using the service correctly, but are also prone to many false positives - for example, sometimes the network may be unavailable or then the data in the remote system changes. So you will also need tests that ...

Write tests against static data files that are based on real web service data. To get test data, you can manually execute requests to the web service and write responses to the file *. You will need to mock the network connection (either using a stub that does not work on the network, or by running the built-in web server in tests and connecting to it instead of the real URL). Thus, you can easily test all kinds of angular cases and error conditions, and the data will always be available and will remain unchanged no matter what happens with a real web service. One caveat is that if the real web service API changes, these tests will not notice it, so you will also need some tests written against the real web service (as mentioned above).

* For example, when I used cron and a small shell script to load every few minutes data from a web service that contained constantly changing schedule information. Collecting such data over the course of several weeks was very useful as test data. Static responses were manually processed from this data, containing all kinds of special cases that I noticed in real data. It was also useful for creating a fake web service and a โ€œtime machineโ€ that reproduced previously recorded data so that our system could be used without access to a real web service.

0
source

All Articles