Creating a AutoMockingContainer with Microsoft Unity - Pretty darn simple.

updated: made container more readable

Just created a little Auto Mocking Container built on Microsoft Unity. It was very very simple.

here's a test that uses it. We tell the container to Returna stub for T because we will want whoever calls resolve<T> on that interface to get the same mock the we will configure in the record() block. In the record() block we Resolve the interface that returns a mock, and tell the mock what to return. later, "real" code resolves the "Runner" class, which is dependent on our two mocks.

[Test]

        public void MockTwoDependenciesForAConstructor()

        {

            MockRepository mocks = new MockRepository();

            AutoMockingUnityContainer container =

                           new AutoMockingUnityContainer(mocks);

            container.WillReturnAStubFor<ILogger>();

            container.WillReturnAStubFor<IEmailer>();

 

            using (mocks.Record())

            {   //Tell our mock to return true when this method is called

                container.Resolve<ILogger>().IsLogFileFull();

                LastCall.Return(true);

            }

            //runner class takes both of these mocks in its constructor

            Runner runner = container.Resolve<Runner>();

            Assert.IsNotNull(runner);

        }

and here's the full code for the container. As you can see it is pretty simple. ContainerControlledLifetimeManager makes sure we have one single instance built for that object during the container's lifetime or until the type is re-registered using the container.

     public class AutoMockingUnityContainer : UnityContainer

    {

        private MockRepository mocks;

        public AutoMockingUnityContainer(MockRepository mocks)

        {

            this.mocks = mocks;

        }

 

        public AutoMockingUnityContainer WillReturnAStubFor<T>() where T : class

        {

            return (AutoMockingUnityContainer) this.RegisterType(typeof(T), null, null, new StubFactory(typeof(T), mocks,Lifetime.Singleton));

        }

 

        public AutoMockingUnityContainer WillCreateMockFor<T>() where T : class

        {

            return (AutoMockingUnityContainer) this.RegisterType(typeof(T), null, null, new MockFactory(typeof(T),mocks,Lifetime.Singleton));

        }

 

        public AutoMockingUnityContainer WillCreatePartialMockFor<T>(Lifetime lifetime) where T : class

        {

            return (AutoMockingUnityContainer) this.RegisterType(typeof(T), null, null, new PartialMockFactory(typeof(T), mocks, lifetime));

        }

 

        private abstract class AbstractFactory : ContainerControlledLifetimeManager

        {

            protected Type theType;

            protected Lifetime lifetime;

 

            protected AbstractFactory(Type theType, MockRepository mocks, Lifetime lifetime)

            {

                this.theType = theType;

                this.lifetime = lifetime;

                this.mocks = mocks;

            }

 

            protected MockRepository mocks;

 

            protected abstract object GetTheObject(Type type);

 

 

            public override object GetValue()

            {

                object value = base.GetValue();

                if (lifetime==Lifetime.NewEveryTime || value == null)

                {

                    value = GetTheObject(theType);

                    SetValue(value);

                }

                return value;

            }

        }

 

        class MockFactory: AbstractFactory

        {

            public MockFactory(Type theType, MockRepository mocks, Lifetime lifetime)

                : base(theType, mocks, lifetime)

            {

            }

 

            protected override object GetTheObject(Type type)

            {

                return mocks.CreateMock(type);

            }

        }

 

        class StubFactory: AbstractFactory

        {

            public StubFactory(Type theType, MockRepository mocks, Lifetime lifetime)

                      : base(theType, mocks, lifetime)

            {

            }

 

            protected override object GetTheObject(Type type)

            {

                return mocks.Stub(type);

            }

        }

 

        class PartialMockFactory: AbstractFactory

        {

            public PartialMockFactory(Type theType, MockRepository mocks,

                          Lifetime lifetime) : base(theType, mocks, lifetime)

            {

            }

 

            protected override object GetTheObject(Type type)

            {

                return mocks.PartialMock(theType);

            }

        }

    }

 

    public enum Lifetime

    {

        Singleton,

        NewEveryTime

    }

Published Monday, April 14, 2008 10:18 AM by RoyOsherove

Comments

Monday, April 21, 2008 11:02 AM by Angelos Petropoulos

# re: Creating a AutoMockingContainer with Microsoft Unity - Pretty darn simple.

Hi,

Love this code, thanks for sharing. I was wondering if you could shed some light into the following problem.

Imagine that the container is setup through a configuration file. I want to re-use this configuration file in my unit test project and selectively "override" dependancies with mock objects.

For example, consider IContractBusinessService, IContractDataService and IAuditDataService. My configuration file effectively does the following

UnityContainer container = new UnityContainer();

container

   .RegisterType<IContractBusinessService, ContractBusinessService>()

   .RegisterType<IAuditDataService, AuditDataService>()

   .RegisterType<IContractDataService, ContractDataService>()

My unit test wants to test an instance of IBusinessService using a mock object for IContractDataService.

Using

container.RegisterInstance<IContractDataService>(mockObject);

does not seem to make a difference as a proper instance of IContractDataService is getting created regardless.

The same goes for the code provided here ...

Monday, April 21, 2008 12:00 PM by Angelos Petropoulos

# re: Creating a AutoMockingContainer with Microsoft Unity - Pretty darn simple.

I have got the functionality I was after by making a slight modification to the code you provided.

By changing

return (AutoMockingUnityContainer) this.RegisterType(typeof(T), null, null, new MockFactory(typeof(T),mocks,Lifetime.Singleton));

to

return (AutoMockingUnityContainer) this.RegisterType(typeof(T), typeof(T), null, new MockFactory(typeof(T),mocks,Lifetime.Singleton));

when I call WillCreateMockFor<T>() after I have already called RegisterType<T>() for the same T, the original registration is now "overwritten". Looks like this does not happen when you pass "null" so passing "typeof(T)" has done the trick.

Monday, April 21, 2008 1:29 PM by Chris Tavares

# re: Creating a AutoMockingContainer with Microsoft Unity - Pretty darn simple.

Roy, thanks, this is great stuff!

Just wanted to mention that Angelos did find a bug in Unity - RegisterType is trumping RegisterInstance. I just checked in a fix, but in the meantime (for anyone else reading this) you can work around the problem by doing:

container.RegisterInstance<IContractDataService, IContractDataService>()

to erase the previous type mapping.

Monday, April 21, 2008 6:22 PM by Gokul

# re: Creating a AutoMockingContainer with Microsoft Unity - Pretty darn simple.

Hi Roy

What is the advantage of using unity over Rhino Mocks. I am pretty new to these technologies. Please throw some light on this subject.

Thanks

Monday, April 21, 2008 9:19 PM by RoyOsherove

# re: Creating a AutoMockingContainer with Microsoft Unity - Pretty darn simple.

Gokul:

look here for a similar discussion and answers

tech.groups.yahoo.com/.../6699

Monday, April 28, 2008 8:01 PM by Don Baechtel

# re: Creating a AutoMockingContainer with Microsoft Unity - Pretty darn simple.

Your container includes MockRepository but does not define it. What is the definition for MockRepository in your code?

Sunday, June 08, 2008 3:30 AM by Nikola Malovic

# re: Creating a AutoMockingContainer with Microsoft Unity - Pretty darn simple.

Roy,

IMHO looking at the test you gave this doesn't look to me as AMC.

If you check out Elutian AMC you would see that there is no need for explicit

          container.WillReturnAStubFor<ILogger>();

container.WillReturnAStubFor<IEmailer>();

on the begining of test.

IMHO, the whole purpose of AMC is to avoid having those lines (which are just shorter forms to register mocks).

AMC should get only the type, which constructor would be examined and those "inject needed mock to container" lines would be performed internaly inside of AMC.

I'm sure you already see the

blog.eleutian.com/.../TestsAutoMockingIoCContainer.aspx

but I still nated to put the link there because comparing their test example and yours clarifies my point :)

Thursday, July 03, 2008 5:48 AM by ISerializable - Roy Osherove's Blog

# Over-testable systems, and mocks as bad test smells

This is an interesting problem I've been running into at work. Sometimes we would try to write a test