Wednesday, September 20, 2006

Mock Object for Testing

 
    Mock: an imitation, pretend, mimics somebody

    I have been using unit testing for some time now, but never really bothered about mock objects. Over time when projects grow, so do unit tests and then unit tests began to look more like integration tests. Objects would call other objects, which in turn calls others all the way to database. Hence after most of the tests, there is a needed to reset database. So to do this we would put some script/db calls in test’s setup and it all works fine like a well oiled machine. Sometimes when we see an occasional red in tests, we can fire up my debugger attach it to NUnit and find the problem.
    So what's the problem? Well unit tests are ‘unit’ tests not integration tests or uat. They should be testing only a unit of code not the whole end to end application. When we see red in NUnit we should be able to know which object’s which function is acting up from tests itself. Hence there is a need to isolate each object and test it separately; here is where Mock object comes in. Mock object is a runtime object which can imitate as some object in a controlled way. It also allows setting mock responses. With mock objects we would be testing only single unit and not whole application. 
   There are lot of frameworks which provides mock object functionality Rhino-mocks , EasyMock.Net, NMock, NUnit.Mocks TypeMock.Net etc, most of them offer similar functionalities
Here is a sample using Nunit.Mocks

using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using NUnit.Mocks;
namespace TestMockObjects
{
    public interface ISomeInterface
    {
       string SomeFunction();
    }

    [TestFixture]
    public class SomeTestClass
    {
        DynamicMock mockObject;
        ISomeInterface someObject;
        [SetUp]
        public void SetUp()
        {
            mockObject = new DynamicMock(typeof(ISomeInterface));
            someObject = (ISomeInterface)mockObject.MockInstance;
            mockObject.SetReturnValue("SomeFunction", "I am Mock");
        }

        [Test]
        public void TestMock()
        {
            Assert.IsTrue("I am Mock" == someObject.SomeFunction());
        }
   }
}

2 comments:

Anonymous said...

Of course you forgot to mention TypeMock.NET that allows you to mock sealed types and static methods...

See a cool article Stop Designing for Testability

Ash said...

Yes i did forgot that..Thanks for pointing out. I have added it.