Mock Objects

25 01 2008

tdd.png

So, you have started reading or doing more on Test Driven Development? Then am sure you would have now heard about Mocking or Mock Objects :D

Before getting started and seeing what is this Mock Object, let me quote the definition of Unit Test from Wikipedia

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, Unit Testing covers testing each individual part in your program. In other words, when we say we are unit testing a Component A, we actually test the functions, properties etc., inside that component.

Below is a pictorial representation of what we do,

unit-test.png

For Component A , we write several unit test cases and test it. Since this component does not depend on anything else, it is fairly easy to test all the parts of the component and hence it satisfies the definition of Unit Testing.

Now we bring in another Component B, which depends on Component A and thus now we have something like this,

unit-test-2.png

How do we test Component B now?

Let me write down the scenario of where we are now,

1) We have Component A which is been tested

2) We have Component B which uses/depends on some of the functions of Component A

3) We have to test Component B such a way that its isolated from Component A, yet still use Component A

4) If we test along with Component A with Component B, its not Unit Test, rather its, Integration Testing!

What do we do now? Mock Component A 8)

Yes, here comes the use of Mock Objects. From Wikipedia,

In object-oriented programming, mock objects are simulated objects that mimic the behavior of real objects in controlled ways. A computer programmer typically creates a mock object to test the behavior of some other object, in much the same way that a car designer uses a crash test dummy to test the behavior of a car during an accident.

So, its kinda Fake Object, but a Mock Object has some expectations and results being set on it.

Now, to make use of Mock Objects, we change the Component A to implement an interface Interface A and Component B an interface Interface B .Using Interfaces helps us to have just the functions and properties of the Component being written which is what Mock needs ;)

Here we are now,

unit-test-3.png

TDD has hence allowed to make changes to your design now and you would have changed tests accordingly.

Introducing Mock Objects, we now have,

unit-test-mocking.png

So, we interact with Component A using our Mock Repository which holds the Mock Object – Interface A

We can now set expectations on Mock Objects, meaning that, you can say that – When a function named FunctionA is called, return the string “Hello World”

It may confuse you initially, but am sure you will get the whole picture once you start mocking yourself ;)

Here is a sample test case along with Mocking (Using NUnit and Rhino Mocks),

[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);
       });
    }
}

More resources on Mock Objects,

1) All about Mock Objects

2) Mock aren’t Stubs

3) Rhino Mocks

About these ads

Actions

Information

3 responses

5 02 2008
David White

Mock objects seem so hard to explain. (Or maybe it is just me who struggles to grasp them.)

Can I suggest you add some comments to the [Test] method?

Eg which object corresponds with ComponentA (presumably Bl.IBLAdmin, mocked with mockAdmin?). What is ComponentB (presumably AdminEntity?) But then I lose it — what exactly about AdminEntity is this test testing? And how do dbAdmin and eduAdmin fit in?

Thanks

5 02 2008
Chaks

@David, Thanks for the comment. Yes, I will explain this small test case in a separate post. You are right, I should have explained it here :D, so will blog about it today!

3 04 2008
Owen Evans

Mock objects are the hardest things to explain to people in my experience. The trouble being that once you get the use of them they become quite a simple concept and you forget how hard it was to understand originally :)

I’ve never found a metaphor for what mocking provides that everyone gets.

There are a few points to remember with mocking:

avoid ordered tests at all costs: remember the purpose of the unit is to provide certain output if an input is received. often ordered tests are mistakenly put in thinking they are important but in fact it’s just the fact that they get called that is important.
avoid strict mocks on objects that don’t matter: By default i use DynamicMock rather than CreateMock in RhinoMocks, why? well i want to be open to refactoring. if my code input and output doesn’t change but i make an extra call to get to this result i really don’t mind. CreateMocks will create a ‘strict’ mock ie. it will throw an exception if something gets called that isn’t expected. a dynamic mock will try and muddle through regardless (returning default values or not caring if its a void call), this creates tests that are less prone to breaking.

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




Follow

Get every new post delivered to your Inbox.

%d bloggers like this: