Refactor your code

by volkanuzun 6/17/2008 1:14:00 AM

As much as i am trying to learn and implement test driven, we have lots of projects in our hands that dont have any unit tests. Writing unit tests to the preexistingg functions are'nt that easy. One of the reasons is most of the functions are heavy-duty workers, they do lots of stuff. Unit testing or at least thinking how to test your functions teaches you to write very simple, short functions; and if you already have heavy duty functions, u try to refactor them. By refactoring, u usually endup having very small functions; a few lines maybe, and also having more independency; if you think about the scraper functions i posted a few days ago, one of them: GetSource was a heavy, obese function. It has more than 1 type of dish on its plate to eat, so let's try to refactor that code, below is the code before refactoring

public string GetSource(string Url)
{
if (Url == String.Empty)
{
this.htmlSource = String.Empty;
return String.Empty;
}

string htmlSource = String.Empty;

if (!(Url.Contains("http")))
Url = "http://" + Url;

try
{

//create a web request
WebRequest request = WebRequest.Create(Url);
WebResponse response = request.GetResponse();
Stream responseStream = response.GetResponseStream();
//himm encoding ? do we need this if everything is english? dunnp
Encoding utf8Encode = Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(responseStream, utf8Encode);
htmlSource = readStream.ReadToEnd();
}
catch
{
htmlSource = String.Empty;
}
this.htmlSource = htmlSource.ToLower();
return htmlSource;
}

 

 The first few lines of code is checking if string is empty, if not, does it have http:// prefix or not. So lets refactor this part, and write a function, below is the small function

public string CheckHttpPrefix(string url)
{
     if(url.Trim() == String.Empty) return String.Empty;
     if(url.Contains("http")) return url;
     return "http://"+url;
}

 

Now the above function is a slim function, not only it is simple to test the function but also it helps to simplify the GetSource() too. The second part we can refactor is, the dependency on the WebRequest and WebResponse. We can write a function that returns a StreamReader and replace it in GetSource(), let's do this

public StreamReader GetStreamReaderFromWeb(string url)
{
     url = CheckHttpPrefix(url);
     if(url==String.Empty) return null;
     StreamReader readStream = null;
     try
     {
         WebRequest request = WebRequest.CreateUrl();
         WebResponse response = request.GetResponse();
         Stream responseStream = response.GetResponse.Stream();
         Encoding utf8Encode = Encoding.GetEncoding("utf-8");
         readStream = new StreamReader(responseStream,utf8Encode);
      }
      catch
     {
         readStream = null;
     }
     return readStream;     
}

 

Now we have a function that checks for http prefix, another function that returns StreamReader. As we return StreamReader from the function, now it should be easy to mock out this function cause any function that returns a streamreader could replace it. Let's recap out GetSource() function changing it so that it takes a streamreader parameter. By doing this, we simplify the unit testing. (cause it is now easier to mock out, if you have the streamreader inside the body of the function not as the parameter, it wont be easy to mockout)

public string GetSource(StreamReader reader)
{
     if(reader ==null) return String.Empty;
     string htmlSource = reader.ReadToEnd();
     return htmlSource;
}

 

Have fun 

Tags:

About the author

Volkan Uzun




E-mail me Send mail

Twitter

Calendar

<<  June 2008  >>
MoTuWeThFrSaSu
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

View posts in large calendar

Flickr Badge

www.flickr.com
This is a Flickr badge showing public photos from volkanuzun. Make your own badge here.

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

Sign in