Wednesday, November 02, 2011

Linq - Select only latest revision

I'm doing a different approach to what I normally do on my new home page. I'm storing all my data with revisions. Update a photo or an article and it is stored in my database with a new revision. A simple entity might look something like this:
Person
--
int id
int revision
string name
Now, my challenge was to retrieve persons from my database, but only the latest revision. So I wrote myself some Linq that looks a bit like this:
public IEnumerable<Person> GetPersons()
{
    return  from person in Person.All()
            group person by person.Id
            into personGroup
            from entity in personGroup
            where entity.Revision == personGroup.Max(x => x.Revision)
            select entity;
}
And it returns a list of unique persons, but only the latest revision of each.

Thursday, October 27, 2011

Unit testing with mock objects

This article is meant as a short tutorial on how to use an isolation framework. I prefer Moq for my .NET projects, but I'm sure there are other good alternatives out there. Moq can be pulled from NuGet. Simply add it to your test project and you're good to go.

When do we use mocking? The answer is, we use mocking when we need to isolate a unit for testing. Let's say I have a method that pulls a resource from the internet, looks at it and returns a list of strings. What we want to test is how different inputs gives different results, not the actual operation of opening the web page and streaming data.

I have some code ready and I will demonstrate how to write some tests for it. In the code below, I download and go through an xml document and look for nodes containing names:
public List<string> FetchData(string url)
{
    // Get XmlDocument using WebClient
    var document = new XmlDocument();
    document.Load(new WebClient().OpenRead(url));
           
    // Go through the document and aggregate a list of strings
    var list = new List<string>();
    foreach (var node in document.GetElementsByTagName("name"))
    {
        list.Add(((XmlNode) node).InnerText);
    }

    return list;
}


Separate concerns

Now, the first thing I have to do is to take out the code that talks to the internet. This way, I can inject different result data and see how it affects the output. I simply set up a wrapper for the WebClient, so that the rest of the code can be isolated for testing. Here's my wrapper class:
public interface IWebClientWrapper
{
    XmlDocument FetchXml(string url);
}

Here's an implementation of my interface:
public class WebClientWrapper : IWebClientWrapper
{
    public XmlDocument FetchXml(string url)
    {
        // Do stuff and return XmlDocument
    }
}

Now, I have a separate unit that speeks with the internet and a separate unit that interprets the results. I've set up the wrapper class with an interface so that it can be mocked for testing. Either that or its methods would have to be marked as virtual.


Prep the code

Next, in my web-fetch-thing-class, I set up a new property, WebClientWrapper. The property has the type IWebClientProxy. If it is not set, it will simply create a new instance. This pattern allows me to inject a custom instance of IWebClientProxy for testing.

private IWebClientWrapper _webClientWrapper;
public IWebClientWrapper WebClientWrapper
{
    get
    {
        if (_webClientWrapper == null)
            _webClientWrapper = new WebClientWrapper();
        return _webClientWrapper;
    }
    set { _webClientWrapper = value; }
}

My FetchData method now looks like this:
public List<string> FetchData(string url)
{
    // Get XmlDocument from the WebClient wrapper class
    var document = WebClientWrapper.FetchXml(url);

    // Go through the document and aggregate a list of strings
    var list = new List<string>();
    foreach (var node in document.GetElementsByTagName("name"))
    {
        list.Add(((XmlNode) node).InnerText);
    }

    return list;
}

Testing the code

Let's take a look at the actual tests. I wanted to test how different results affects how my method aggregates a list of names. Let's start with some code:
var webClientWrapper = new Mock<IWebClientWrapper>();
webClientWrapper
   .Setup(x => x.FetchXml(It.IsAny<string>()))
   .Returns((XmlDocument)null);

In the snippet above, we've created a new instance of a Mock class of the type IWebClientWrapper. We've set up the method FetchXml(...) to take any input, so long as it is of the type String and we've stated that it should return null. Note how we have to do casting when we want to return null. This is because the Return(...) method has overloads, and we have to explicitly tell which one we are using.

Next, have a look at how we inject the mock object. Remember how I made the WebClient wrapper into a property?
var webFetcher = new WebFetcher 
                 { 
                    WebClientWrapper = webClientWrapper.Object 
                 };

Now, I can excute my method, and see how it behaves. I actually want it to throw an exception if the WebClient returns null. Have a look at the full test:
[TestMethod]
[ExpectedException(typeof(Exception), AllowDerivedTypes = true)]
public void WebFetcher_TestWithNullDocument_ShouldThrowException()
{
    // Setup
    var webClientWrapper = new Mock<IWebClientWrapper>();
    webClientWrapper.Setup(x => x.FetchXml(It.IsAny<string>())).Returns((XmlDocument)null);

    var webFetcher = new WebFetcher 
                     { 
                        WebClientWrapper = webClientWrapper.Object 
                     };

    // Execute
    webFetcher.FetchData("http://www.somewhere.com/validUrl/");
}

I also want to see how the results are when we provide a valid xml document. Have a look at the following test:
[TestMethod]
public void WebFetcher_TestWithValidExampleData_ShouldReturnXmlDocument()
{
    // Setup
    var document = new XmlDocument();
    document.LoadXml("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><names><name>Brian</name><name>John</name></names>");

    var webClientWrapper = new Mock<IWebClientWrapper>();
    webClientWrapper.Setup(x => x.FetchXml(It.IsAny<string>())).Returns(document);

    var webFetcher = new WebFetcher 
                     { 
                        WebClientWrapper = webClientWrapper.Object 
                     };

    // Execute
    var list = webFetcher.FetchData("http://www.somewhere.com/validUrl/");

    // Assert
    Assert.IsNotNull(list);
    Assert.IsInstanceOfType(list, typeof (List));
    Assert.IsTrue(list.Count != 0);
    Assert.IsTrue(list.Contains("Brian"));
    Assert.IsTrue(list.Contains("John"));
}

I will have to make some changes in my original code. At least now, It's more testable and I can see how different input data affects the output.

The code is posted on Bitbucket if you want to have a look:
https://bitbucket.org/andersnygaard/webfetcherthingy/src

Friday, July 22, 2011

DOS on Dope - ASP.NET MVC the old school way

Would you like to combine old school DOS skills with modern day web frameworks? Then DOS on dope might be something for you. Everything is written in DOS .bat scripts. Yes, everything. Views and controllers are all familiar .bat scripts.

I've set up a small home page with a single Index view under a Home controller as you would expect from a simple MVC application. Here's the source:
@echo off
call ..\..\Views\Shared\_header Web Page
call ..\..\h\h1 Welcome to my web page

echo [strong] This web page is under construction [/strong]

echo.
echo [blockquote]
echo [ul]
pushd %cd%
cd ..
FOR /F "delims=~" %%A IN (' DIR /B/a:d') DO (
echo [li][a href='%%A/']%%A[/a][/li]
)
echo [/ul]
echo [/blockquote]

echo [table]
echo [tr]
echo [td]
echo [img src = "Content/anders.jpeg" width = "150"][/img]
echo [/td]
echo [td width = "400" valign = "top"]
echo Hi, I am Anders, and this is my web page. Feel free to browse around and explore my life and works.
echo [br]
echo [br]
echo Be shure you head over to
echo [a href = "http://dod.codeplex.com/"]http://dod.codeplex.com/[/a]
echo where you can learn how to make your own web page
echo [/td]
echo [/tr]
echo [/table]
echo [blink][a href = "Content/index.bat.txt"]Forget Razor, check out this awesome MVC syntax[/a][blink]

::echo [blockquote][pre]"C:\Temp\Blog\Controllers\Home\Index.bat"[/pre][/blockquote]


Nice, or what?


Links:
http://external2.webtop.no/dodblog/
http://dod.codeplex.com/

Friday, July 15, 2011

Code kata challenge #2

I've been playing around with linq-like functionality as a code kata the last few days. I've simplified the my Where method and made a simple skip and take function. I can now do this without the actual linq namespace:

var results = list
.Skip(2)
.Take(200)
.Where(x => x % 2 == 0);


My Skip method:

public static IEnumerable<T> Skip<T>(
this IEnumerable<T> list, int count)
{
var enumerator = list.GetEnumerator();
for (var i = 0; i < count; i++)
enumerator.MoveNext();

while (enumerator.MoveNext())
yield return enumerator.Current;
}


My Take method:

public static IEnumerable<T> Take<T>(
this IEnumerable<T> list, int count)
{
var enumerator = list.GetEnumerator();
enumerator.MoveNext();
for (var i = 0; i < count; i++)
{
yield return enumerator.Current;
enumerator.MoveNext();
}
}


My Where method:

public static IEnumerable<T> Where<T>(
this IEnumerable<T> list, Predicate<T> expression)
{
foreach(var item in list)
if(expression(item))
yield return item;
}


It's darned fast too. Delayed excecution rocks.

Tuesday, July 12, 2011

Code kata challenge

Code kata is a term coined by Dave Thomas, author of several programming books. He suggest you do small exercises regularly in order to keep yourself fit as a programmer.

No doubt, this can be usefull, but doing a small bank account example ten times over doesn't make you fully capable of writing financial applications. In the real world you are likely to meet real world challenges.

Now, what I like are challenges that make me better at core features or work methods. I like challenges like "here's a set of tests, write the method that makes them all pass". If you're good at that, you we'll be better at working with unit tests (TDD in fact).

After watching Justin Etheredge on Linq over at Tekpub, I've got an idea for a code kata. Recreate the Linq functions like Justin does in episode 1. Once you've got the hang of one, move to the next. That should keep you busy for the next month or so and you will be the master of new language features like extension methods, collection initializers, delegates, anonymous delegates, and lambas.

Here's how you might extend IEnumerable in order to implement a WHERE method:
using System;
using System.Collections.Generic;

namespace Linq.Kata
{
public static IEnumerable<T> Where<T>(
this IEnumerable<T> list, Predicate<T> expression)
{
foreach(var item in list)
if(expression(item))
yield return item;
}
}
This method extends IEnumerable and takes a function delegate as parameter. We traverse the list and execute the delegate function on each item in the list. The method would be called like this:
var integerlist = new int[] {1, 2, 3, 4, 5, 6};
var integerResukts = integerlist.KataWhere(x => x % 2 == 0);

var stringList = new string[] {"anders", "christian"};
var stringResults = stringList.KataWhere(x => x == "anders");

Some links:

Kata Catalogue
http://codingdojo.org/cgi-bin/wiki.pl?KataCatalogue

Mastering Linq @ Tekpub
http://tekpub.com/view/linq/1

Wednesday, June 29, 2011

Scalable source control

I recently started a small pet project. Using ASP.NET MVC3 with EF Code First, I think I've managed to keep it all small and tidy. But, if you add a set of tests, a bit of advanced jQuery in the front end and a custom authentication service on top of that, it's time to add a source control system. Here's what I've done as my project has grown:

- Day one, I placed my project in a Dropbox folder. That way, I could reach my project files from all my computers (and even my iPhone).

- A few weeks later, when I first had to make some serious changes and needed a fallback, I created a Mercurial repository in my Dropbox folder and commited all my code. I've got a blogpost on that here: http://csharptutorial.blogspot.com/2011/06/using-dropbox-with-mercurial.html. Mercurial is a great source control system, because it doesn't require a server installation and your repository is copied to all locations where it's checked out.

- Now, I'm looking at moving my project over to BitBucket (http://bitbucket.org/) which is a free hosting service (up to five users I think). It allows you to share code and has an issue tracker system.

A good alternative to Mercurial is Git, using github.com in stead of bitbucket.org. Both have a learning curve, but they both represent modern version control tools and is well worth having a look at.

Thursday, June 09, 2011

Using DropBox with Mercurial

Here's a short guide to setup a Mercurial repository in a DropBox folder. You'll need a DropBox account set up and Turtoise Hg installed.

First, create a DropBox folder for your Hg repository. I've got a project called Places, so I created a directory ./Projects/HGRepositories/Places



Inside your project directory, right click anywhere, then go TortoiseHg->Create Repository Here



Follow the instructions. The destination directory should be the same as the one with your project.



After you've finished initializing your repository, you should have the .hg folder and the .hgignore file added to your directory.



Set up the ignore list.



Copy the entire project directory over to your DropBox directory



Next, from your project directory, open the Hg Repository Explorer.



From the Repository Explorer, Commit your project.







Now, push your changesets to the DropBox repository.



And there you go. Your repository now has backup and is available from any computer that has access to your DropBox folders. In order to check out at another computer. Create an empty folder. Inside it, right click and choose TortoiseHg->Clone and clone the repository from the shared DropBox folder.