Archive

Archive for the ‘TDD’ Category

Setting non-public property with type safety (no more strings)

November 30th, 2008 No comments

Sometimes I have a property where the get-part is public and the set-part is private or protected. Like this:

public class Forum

{

    public virtual int TopicCount { get; protected set; }

 

    // More code...

}

There can be various reasons for this design. For me it is often when I make database optimizations where I don’t want to be able to change a property directly in the code, but instead do it directly against the database.

Still, sometimes I want to set the value in unit tests. How do I do that?

Before C# 3.0 I had to rely on having a string with the property name and then use reflection. The main disadvantage with this approach is that if you rename the property you have to make sure that the string is also changed, which is time-consuming and error-prone.

So, with C# 3.0 you no longer need that string. You could use the new Expression-tree feature like this instead:

protected static void SetProperty<TObj, TValue>(TObj obj,

    Expression<Func<TObj, TValue>> property, TValue value)

{

    var propertyInfo = (PropertyInfo)((MemberExpression)property.Body).Member;           

    propertyInfo.SetValue(obj, value, null);

}

I have placed this method in my BaseTest class, since I only use it in my tests. Now you can write code like this to set the property:

var forum = new Forum();

SetProperty(forum, f => f.TopicCount, 2);

This is only a scratch on the surface of what you can accomplish with Expression-trees.

Categories: .NET, TDD Tags:

Testing your NHibernate data access code using SQLite

November 25th, 2008 No comments

Ever since I started working professionally at a software company (which is roughly 3 years ago) I’ve been doing unit testing. I really consider automatic testing one of the most (if not THE most) important trends of software development the last decade.

But, despite that, I’ve let code close to the data access be left untested. This has been due to the pain I thought it would be to create and maintain those tests. And also I’ve thought that those tests would be way to slow to have among my other unit tests (which we want to be fast, so that we run them often).

For the first two years of my career this was not a big problem. We rarely had bugs in our data access code as it mostly consisted of simple, straight forward code. So I hadn’t really given it much thought. Until lately that is.

Then we started to get performance issues as we got some really large organizations to use or software. To resolve the performance issues we made our data access smarter so it could make more efficient queries to the database. As smarter often means more code, or at least added complexity, I saw the need of automatic tests to guarantee the quality of the code.

So, I read some articles on using SQLite with NHibernate. After some pain setting it all up, I accomplished my goal of easy data access testing. So say that I want to test GetCustomerByName in the following class (in real life I wouldn’t test methods that are this simple, but it’s just to show the idea):

public class CustomerDao

{

    private readonly INHibernateManager _sessionManager;

 

    public CustomerDao(INHibernateManager sessionManager)

    {

        _sessionManager = sessionManager;

    }

 

    public Customer GetCustomerByName(string name)

    {

        var session = _sessionManager.CurrentSession;

 

        return session.CreateQuery("from Customer where Name = :name")

            .SetParameter("name", name)

            .UniqueResult<Customer>();

    }

}

Then I can write a test like this:

public class CustomerDaoTest : BaseTest

{

    [Test]

    public void CanGetCustomerByName()

    {

        Database.Init();

        var customerA = new Customer { Name = "A" };

        var customerB = new Customer { Name = "B" };             

        Database.Save(customerA, customerB);       

        var customerDao = new CustomerDao(Database);

 

        var result = customerDao.GetCustomerByName("B");

 

        Assert.That(result, Is.EqualTo(customerB));

    }

}

For this to work I have a class called TestDatabase with the following code:

public class TestDatabase : INHibernateManager

{

    private static ISessionFactory m_sessionFactory;       

    private static SchemaExport SchemaExport;

    private ISession m_session;

 

    public void Init()

    {

        if (m_sessionFactory == null)

        {

            Configuration config = CreateNHibernateConfig();

 

            m_sessionFactory = config.BuildSessionFactory();

 

            SchemaExport = new SchemaExport(config);

        }

        if (m_session != null)

        {

            m_session.Close();

        }

        m_session = m_sessionFactory.OpenSession();

        m_session.BeginTransaction();

 

        var connection = m_session.Connection;

        SchemaExport.Execute(false, true, false, false, connection, null);

    }

 

    private static Configuration CreateNHibernateConfig()

    {

        Configuration config = new Configuration();

        config.Properties.Clear();

 

        config.SetProperty("hibernate.connection.driver_class",

            "NHibernate.Driver.SQLite20Driver");

        config.SetProperty("hibernate.dialect", "NHibernate.Dialect.SQLiteDialect");

        config.SetProperty("hibernate.connection.connection_string",

            "Data Source=:memory:;Version=3;New=True;");

        config.SetProperty("hibernate.cache.use_second_level_cache", "false");

        config.SetProperty("hibernate.hbm2ddl.auto", "create");

 

        config.AddAssembly("MyAssembly"); // Change this to your assembly

 

        return config;

    }

 

    public ISession Session

    {

        get { return m_session; }

    }

 

    public void Save(params object[] entities)

    {

        foreach (var entity in entities)

        {

            Session.Save(entity);

        }

        Session.Flush();

    }

 

    ISession INHibernateManager.CurrentSession

    {

        get { return m_session; }

    }

}

And I’ve also added the following field to my BaseTest class:

[TestFixture]

public class BaseTest

{

    protected readonly TestDatabase Database = new TestDatabase();

 

    // More code here...

}

So, in summary, I’ve shown a pretty easy way of doing database testing. Even though the method under test was really simple in the example, the same technique could be used for much more complex scenarios.

Categories: .NET, NHibernate, TDD Tags:

AutoStub parameters using Rhino Mocks

November 16th, 2008 No comments

For the last years I’ve been using dependency injection for my service classes. More recently (by the introduction of ASP.NET MVC) that have also been the case for my controller classes. I take in their dependencies via the constructor and then let a Dependency Injection/Inversion of Control (DI/IoC) framework automatically resolve and create the classes. I’ve been using Castle Windsor for this, which has worked really well.

However, when it comes to testing service/controller classes, I’ve previously created (often stubbed) the parameters needed when testing, and then given them manually to the constructor. Like this:

var customerDao = Stub<OrderDao>();

var orderDao = Stub<OrderDao>();

var controller = new CustomerController(customerDao, orderDao);

This has proven to be quite fragile as the dependencies to the service/controller class has changed. Often, the case has been that more dependencies have been added as parameters to the constructor. I know, I know, that might be a code smell that the service/controller should be split into smaller classes… But anyway, code smell or not, the fragility of the tests is a problem.

A while back I read about an AutoMocking container, but thought it was a bit cumbersome to have to use both a Mocking framework and a DI/IoC container in my tests. So, I thought that this should be possibly to accomplish with only a mocking framework and a bit of reflection magic. And it actually turned out to be really easy to do.

As a mocking framework I use Rhino Mocks (btw, I love the new AAA syntax in 3.5!). All my test inherit from a class called BaseTest, which is where I decided to put the autostubbing. The code comes here:

[TestFixture]

public class BaseTest

{

    protected static T Stub<T>(params object[] parameters) where T : class

    {

        return MockRepository.GenerateStub<T>(parameters);

    }

 

    protected static T Mock<T>(params object[] parameters) where T : class

    {

        return MockRepository.GenerateMock<T>(parameters);

    }

 

    protected static T CreateAndAutoStubParameters<T>(params object[] parameters)

    {

        return (T)CreateAndAutoStubParameters(typeof(T), parameters);

    }

 

    protected static object CreateAndAutoStubParameters(Type type,

        params object[] parameters)

    {

        var constructor = type.GetConstructors(

            BindingFlags.Public | BindingFlags.Instance)[0];

        var parameterInfos = constructor.GetParameters();

        var constructorParams = GetConstructorParameters(

            parameterInfos, parameters);

 

        return constructor.Invoke(constructorParams.ToArray());

    }

 

    private static List<object> GetConstructorParameters(ParameterInfo[] parameterInfos,

        params object[] parameters)

    {

        var constructorParams = new List<object>();

        foreach (var info in parameterInfos)

        {

            constructorParams.Add(GetParameter(info, parameters));

        }

        return constructorParams;

    }

 

    private static object GetParameter(ParameterInfo info,

        object[] candidateParameters)

    {

        foreach (var candidate in candidateParameters)

        {

            if (info.ParameterType.IsAssignableFrom(candidate.GetType()))

            {

                return candidate;

            }

        }

        return AutoStub(info.ParameterType);

    }

 

    protected static T AutoStub<T>() where T : class

    {

        return (T)AutoStub(typeof(T));

    }

 

    protected static object AutoStub(Type type)

    {

        if (type.IsInterface)

        {

            return MockRepository.GenerateStub(type);

        }

 

        var constructor = type.GetConstructors(

            BindingFlags.Public | BindingFlags.Instance)[0];

        var parameterInfos = constructor.GetParameters();

        var constructorParams = GetConstructorParameters(parameterInfos);

 

        return MockRepository.GenerateStub(type, constructorParams.ToArray());

    }

}

So, now let us assume you want to test a CustomerController with dependencies like this:

public class CustomerController

{

    public CustomerController(CustomerDao customerDao, OrderDao orderDao)

    {

        // Code here..

    }

 

    // Code here..

}

Then you only have to write this:

var controller = CreateAndAutoStubParameters<CustomerController>();

to create the controller with stubs automatically created as constructor parameters.
Often, you might want to have some control over one of the parameters, and then you could write like this:

var customerDao = AutoStub<CustomerDao>();

customerDao.Stub(c => c.GetById(1)).Return(new Customer());

var controller = CreateAndAutoStubParameters<CustomerController>(customerDao);

This way of testing service and controller classes has removed some of the pain of starting to test classes with dependencies that need to be mocked or stubbed.

Categories: .NET, Rhino Mocks, TDD Tags:

JAOO 2007 – TDD tutorial with Robert C. Martin

September 30th, 2007 No comments

I arrived yesterday to Aarhus in Denmark for the ongoing JAOO conference. I’m here for two tutorials, one about Test-driven development (TDD) which I went to today, and one about domain-driven development (DDD) which I will visit tomorrow.

The TDD tutuorial was held by Robert C. Martin, also called Uncle Bob, whom have written a couple of books (none of which I have read yet, unfortunately). I found Robert to be charismatic, loud-mouthed (not in a negative way) and generally a funny guy.

The tutorial begun with a short introduction of TDD and then went on with a presentation of the requirements to a game called “Hunt the Wumpus” (wtf is a Wumpus?!). The requirements were written in a tool called FitNesse. FitNesse is a popular tool for writing what is called acceptance tests. These acceptance tests should non-programmers, typically QA or management people, be able to write.

After the introduction we were given an incomplete implementation of the game, along with a lot of acceptance tests which didn’t pass. Our objective was to use TDD and write code to make the acceptance tests pass. Every change we made to the game code had to be as an effect of creating a unit test that failed.

I’ve personally been writing unit tests for two years now, but haven’t done any real TDD until very recently. So I’m still in the process of re-learning the way to write code. In TDD you should “Write the test that force you write the code you want” as Robert so elegantly put it. More formally there are three rules of TDD which are:

  1. You are not allowed to write any production code unless it is to make a failing unit test pass.
  2. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
  3. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.

If you practice TDD properly you should, accordingly to Robert, produce more than 1000 unit tests per year. That is a lot more than what I’ve produced my last year! And then I actually thought that I had been writing a lot of tests.. But when you think about it, it’s not really an unreasonable amount. Knock it out over a year and it’s just about 4 tests per day. Now it didn’t sound so much, did it?

Throughout the day, Robert interrupted regularly to ask the audience questions and share his opinions about difference aspects of software development. I will present some of the nuggets here:

“Comments are dirt in code”. My favourite! What he means is that most of the time comments in code try to make up for poor design. If the design was really good, the comments wouldn’t be needed. I really agree with this reasoning when it regards that comments shouldn’t be needed inside code blocks. However, public comments that clarifies, for example what state a parameter must have (not null is common), I still think are needed sometimes, especially for APIs where you don’t have access to the source code.

“Implement new functionality in priority order, not what is convenient from a design point-of-view”. This sentence stuck since we’ve been discussing this lately at the company I work for. The reasoning behind it (besides the obvious point that high priorities are more important than low priorites) is that the design should be refactored continually so that the best possibly design will emerge independently of the order that the tasks are implemented.

He also gave so guidelines of method design. A well-designed method should:

  • not be longer than 5 lines of code
  • not have indentation depth (like for and if statements) of more than 2
  • not have more than 2-3 parameters

Personally, I’m not quite there yet when it comes to the first two statements. I try to make my methods short, but sometimes they are up to 30 lines of code.. And my indentation depth often goes up to three or sometimes even four.

At the end of the tutorial, there was time for reflections of working with TDD and a question from the audience was that they had gotten redundancies where some unit tests were almost identical as some of the acceptance tests. This was okay, according to Robert.

On the negative side I don’t have much to say.. Perhaps only that he at one time used exception handling for taking care of bad user input from the command line. In my book*, exception handling should only be used for exceptional events, not such a common case as when a user misspells a command..

All in all, I found the tutorial very giving and inspirational. How much the tutorial will affect my development process, I don’t know yet.. But I think I’ve gotten enough knowledge and energy to really start doing real test-driven development from now on. It will be fun to reflect upon this in a couple of weeks.

* No, I haven’t written any books. I mean the figure of speech.

Categories: TDD Tags: