Thursday, October 15, 2009

Budget App - Part 4 : Test Driven Development with Moq - An New .Net Mocking Framework

I recently found a relatively new Mocking Framework called Moq. Daniel Cazzulino provides a nice introduction and reason for developing the new framework. Considering that this is built on the concept of Linq to Mock and that I enjoy working with Linq I thought I'd give it ago as I continue to develop the data services to my Budget application with a TDD approach.

I'm going to following the principles of TDD as I understand them:
  1. Write the test first - it'll probably not compile.
  2. Get the test to compile.
  3. Get the test to pass - with the least amount of code.
  4. Create another test that will cause your code to fail.
  5. Refactor your class so that both tests pass.
Write the test first
As I've been refactoring my code I've come across the follow functionality...

private bool DoesMonthYearExis( int month, int year )
{
    bool exists = false;

    var months = ( from m in budgetEntities.MthSet
                   where m.Month == month && m.Year == year
                   select m ).ToList();

    if ( months.Count > 0 )
    {
        exists = true;
    }

    return exists;
}

There will obviously be a number of steps involved in turning this into a WCF Service call, but the first step is to ensure that the DataService will do what it's suppose to do. So how do we do this using a TDD approach? Firstly we write our test.



So here we have our first test using the new Moq framework. As you can see the data service interface doesn't have a definition for a method called DoesMonthYearExist(...) hence it won't compile, which leads to...

Getting the test to compile
To get this to compile we need to update the Interface as well as it's implementing class. We need to remember that we write the least amount of code as possible.



This obviously isn't very useful, but it should give you point. The test will now compile however it will fail. If you look at the test above there we have set up a number of expectations with Moq and these aren't being met. Now let's...

Get the test to pass
Don't forget to write as little code as possible.


You can see that the expectations will now be met with repo.Query() returning a value and the repo object being disposed.

This is all good, but we know that the code is not really doing what we need it to do and this is when we...

Create another test that will cause your code to fail
Not a huge difference, but it's enough.


We've changed the year being tested for and are now expecting that the combination of month and year will not be found.

Refactor your class so that both tests pass
Here we make our implementation do what it's supposed to do.



What does this leave us with? A well tested method that has good coverage

Moq
I must say that I do like not having to indicate what expectations have to be recorded and then play them back, you just say this object has certain expectations and that's it.

Despite simple examples Moq looks like a nice mocking framework to work with.

Enjoy!

No comments:

Post a Comment