Revisiting Mock Objects

5 02 2008

My last post on Mock Objects explained briefly about what is Mocking and gave you an example. But that example is not explained and thought let me explain and how Mocking plays its part here.

So, revisiting that example,

[TestFixture]
public class AdminTests
{
    private MockRepository mocks;
    private EduAdmin eduAdmin;
    private Bl.IBLAdmin mockAdmin;
    private delegate bool ValidRegisterDelegate(Db.Admin entity);

    [SetUp]
    public void Setup()
    {
         mocks= new MockRepository();

         mockAdmin = mocks.DynamicMock<Bl.IBLAdmin>();
    }

    [Test]
    public void Check_Method_Register()
    {
        AdminEntity inputEntity = new AdminEntity();
        inputEntity.AdminId = “admin”;
        inputEntity.AdminPassword = “admin”;

        Db.Admin dbAdmin=new Educator.DataAccess.Admin
        {
            AdminId = “admin”,
            AdminPwd = “admin”
        };

        With.Mocks(mocks).Expecting(() =>
        {
            Expect
                .Call(mockAdmin.Translate(inputEntity))
                .Return(dbAdmin);

            Expect
                .Call(delegate { mockAdmin.Insert(dbAdmin); })
                .Callback((ValidRegisterDelegate)
                               ((entity) => { return entity.AdminId == “admin” && entity.AdminPwd == “admin”; }));

        }).Verify(delegate
       {
           eduAdmin = new EduAdmin(mockAdmin);

           eduAdmin.RegisterAdmin(inputEntity);
       });
    }
}

To explain the above example, consider this diagram

mock-objects-1.png

(Please consider the line separation, I will come to it later, Ignore the Tests)

So, as the diagram explains, we have,

1) EduAdmin which is our Service Layer (SL)

2) IBLAdmin which is our Business Layer (BL) Interface, and,

3) Database Layer (DL)

The BL interacts with DL to perform database operations and SL sends requests to BL in regard to what needs to be done.

So, what does the above example test function do? Here it is,

flow.png

Revisiting again the definition of Unit Testing,

In computer programming, unit testing is a procedure used to validate that individual units of source code are working properly. A unit is the smallest testable part of an application.

The goal of unit testing is to isolate each part of the program and show that the individual parts are correct. A unit test provides a strict, written contract that the piece of code must satisfy.

So, testing this RegisterAdmin function involves the use of BL as well DL (via the BL). And also from the first diagram, we do show that each layer is tested against their own tests. So, using Mock Objects, now we come down to,

mock-objects.png

Since we have mocked our BL, we can now write expectations on how it has to behave and what results it has to give for our Service Layer to work properly :)

To dig deep, we may have something like this,

bl-sl.png

Admin is a class that implements our Interface IBLAdmin and AdminEntity is business type and DB.Admin is a database type.With Mocking, we don’t care about the Class but the Interface. EduAdmin is our Service Layer class and it has a function RegisterAdmin

So, to RegisterAdmin function to work properly, we have to see that the BL’s Translate and Insert functions return proper results and those are nothing but setting expectations on our mock object which is IBLAdmin 8) . If you think slowly where we are, you will probably get what is Mocking ;)

Here is that part which sets expectations and tells what should be returned respectively

        With.Mocks(mocks).Expecting(() =>
        {
            Expect
                .Call(mockAdmin.Translate(inputEntity))
                .Return(dbAdmin);

            Expect
                .Call(delegate { mockAdmin.Insert(dbAdmin); })
                .Callback((ValidRegisterDelegate)
                               ((entity) => { return entity.AdminId == “admin” && entity.AdminPwd == “admin”; }));

        }).Verify(delegate
       {
           eduAdmin = new EduAdmin(mockAdmin);

           eduAdmin.RegisterAdmin(inputEntity);
       });

What does that ValidRegisterDelegate do? It checks whether the input parameters that is being used to invoke Insert function is of expected type and has expected values. Its more of a RhinoMocks feature, so once you start using it, you will get used to it :D . And RhinoMocks follows the Record and ReplayAll method where we set expectations means that we record something and once we say to verify, it replays all the set expectations when invoked.

The expectations we set are very simple. When the Translate function is called with an input parameter of type AdminEntity, return an object of type Db.Admin . Similarly for Insert function, except that we don’t return anything.

In the Verify stage, we can see that we create a new instance of our SL by passing the BL Interface object. What are we doing here? Welcome to the world of Dependency Injection :D . We explicitly tell that – “Hey, here is my BL object which you have to use and please use this“. We inject dependency here! So, now the BL object is already in the MockRepository and when we tell our SL to use this object, it means that its going to use the MockRepository object with expectations set on it 8)

I think now things are getting clear and you should be able to understand this diagram way better than earlier :) (which is also shown above)

mock-objects.png

Coming back to Dependency Injection – You may be wondering that so if my client uses this SL, will he always have to explicitly tell that this is my BL and use it? – NO. The way we overcome is using multiple constructors :)

public class EduAdmin
{
     private IBLAdmin blAdmin;

     public EduAdmin(IBLAdmin mockAdmin)
     { blAdmin=mockAdmin;}

      public EduAdmin() : this(new Admin())
     { }
}

I think thats self explanatory on what we do ;)

Hope this explained how we Mock 8)

If you have any doubts, please do leave your comments and I will try to answer them :)





Windows Server 2008 and Vista SP1 are now RTM

5 02 2008

                              windows-server-2008.jpg

After a long wait, Microsoft today announced that Windows Server 2008 and Vista SP1 are now RTM!

Windows Server 2008 is available in Connect for a small time period of 30 days (without product keys though) and in MSDN/TechNet subscriptions from today, but Vista SP1 will only be available to public from mid of March. But that said, even we Beta Testers haven’t received our Vista SP1 copy yet 8)

Cant wait to install final Vista SP1 :D








Follow

Get every new post delivered to your Inbox.