Sunday, May 22, 2011

Unit Testing Unity 2.0 Registrations


One of the areas I don't test as well as I should are the bindings of my IoC containers. I'm making a conscious effort to change that. Really, in the end, TDD is all about not writing any code without a failing test. So I came up with a way to test the bindings that are registered by my registration class.

Here's the extension method which I'm now using to help test Unity 2.0 bindings:

public static class MappingTestExtensions
    {
        public static void ShouldHaveMapping<TFrom, TTo>(this IUnityContainer container)
        {
            var registration = container.Registrations
                .FirstOrDefault(o => o.RegisteredType.Name == typeof (TFrom).Name);
            Assert.That(registration, Is.Not.Null,
                        "Could not find the mapped type {0}",
                        typeof (TFrom));
            Assert.That(registration.MappedToType.Name == typeof (TTo).Name,
                        "Type {0} was not mapped to type {1}",
                        typeof (TFrom),
                        typeof (TTo));
        }
    } 

The names of the types are being used, because I couldn't get a direct type comparison to work. When I get a bit of time, I plan to research that further.

I've been using Context Specification style test naming for a couple months, and have really grown to like it. Rolled into the base ContextSpecification class is a an auto mocking container which is largely taken from an ElegantCode blog post. With that in mind, an example class would look like this:

public static class UnityBootstrapTests
{
        public class UnityBootstrapBehavior : ContextSpecification
        {
            protected UnityBootstrap Sut;

            protected override void Context()
            {
                Container.RegisterInstance<IUnityContainer>(new UnityContainer());

                Sut = Container.Resolve<UnityBootstrap>();
            }
        }

        [TestClass]
        public class WhenPassedAContainer : UnityBootstrapBehavior
        {
            protected override void BecauseOf()
            {
                Sut.SetDependencies(Container.Resolve<IUnityContainer>());
            }

            [TestMethod]
            public void ShouldRegisterAuthenticationFacade()
            {
                Container.Resolve<IUnityContainer>()
                    .ShouldHaveMapping<IAuthenticationFacade, AuthenticationFacade>();
            }

            [TestMethod]
            public void ShouldRegisterDaoClass()
            {
                Container.Resolve<IUnityContainer>()
                    .ShouldHaveMapping<ISupportsDataAccess, DefaultDao>();
            }
        }

    }

I then  did some googling to see how my solution stacked up. One msdn blog post used techniques which are no longer available in Unity 2.0 (but would help if you're still using 1.x). A Patterns and Practices article had a solution which very closely matched mine. It also includes how to check for a singleton registration.