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 😀 . 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 😀 . 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 🙂

Advertisements

Actions

Information

3 responses

6 02 2008
David White

I appreciate your extra effort to clarify this. I understand the concept of Dependency Injection.

Please correct me if I’m wrong, but this is what I think you are saying:

In the “Expecting” phase, we write what the mock object should experience in the “Verifying” phase. Such as, what methods are called, with exactly the right method signatures and with the appropriate object returned. Does it test that the object contains the right data, too?

That doesn’t sound right to me — I’ll try again. We are actually testing the Service Layer. So we’re not interested in what happens behind the scenes in the BL. So the “Expecting” phase is just telling the mock object what to return to the SL? But then I don’t get it, since there are no Assert statements.

What is the mock object doing? Clever reflection stuff?

7 02 2008
Chaks

@David, you are right with this,

“In the “Expecting” phase, we write what the mock object should experience in the “Verifying” phase. Such as, what methods are called, with exactly the right method signatures and with the appropriate object returned.”

Yes, you can test for the right data using the Mock Callback which you can see in my test case. It just gives you complete code coverage 😉

Coming to the Assert statements, in this particular test I don’t have anything to assert. But if you ask me how I deal if any error occurs in my SL, I use exceptions and raised if problems occur and that goes as a separate test 🙂

7 02 2008
Ivan Porto Carrero

a mock object is a proxy wrapper around an interface or a class effectively replacing the methods on that class.
it provides empty implementations from which you can control the return value and verify with which parameters it has been called etc. That happens during the Recording phase. You’re then effectively writing methods through some sort of dsl like implementation.
After that you enter a replay phase in which the methods can be called and the mock will provide implementations for those methods.
After you can enter a verification phase in which you are calling the callbacks etc to verify that things executed correctly.

So you can test the behavior of your unit under test (generally a method) in a totally isolated and controlled way without having to make sure the whole state of the application is favourable for your current test.

hope that helps.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: