Mock Objects are something that I hear more and more and more and more about as I continue my path into the TDD world, and even from some not in the TDD world. They are a wonderful tool for helping you to create code for tests that hasn't been implemented yet. Or to help test your data access code without having to run to the database every time you run a test. Before we go much further lets get a more "formal" definition of Mock Objects. For that lets visit 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.
To use Rhino Mocks first you need to download Rhino Mocks then unzip it somewhere on your hard drive. Then in your projects just go to add references in the solution explorer then the browse tab then find the assembly where you unzipped it and tada you are read to start.
So let me introduce you to basically what the application is I wrote to mess with mock objects.
First, let me tell you I don't completely understand what is going on with Rhino Mocks and "how" it works. At this point I know just enough to start "using" mock objects and that is what I want to pass on to you today. I assembled this code together from around 20 different tutorials so please do not look at this as best practices. So in typical TDD fashion lets start with test. (I am including the top portion of the file so you can see what I have above the actual test)
Firstly, don't forget to add references to NUnit and your Rhino Mocks assemblies. You will also need to setup all the appropriate attributes for your tests. If you do not know how to do this please visit my Part 2 of TDD for Beginners.
MockRepository mock = new MockRepository();
This is the object you create initially that will store all of your mock objects that you are going to be using. (That is what I gather from what it does and the name)
IWorld world = mock.CreateMock<IWorld>();
As best I understand this code we are creating an instance of IWorld object as if it was an object that inherited from IWorld.
From my understanding this basically will run and in this block of code is where we load our mock object with what the objects will do. Like we are going to basically say what the world object is going to do.
With this we just told our mock object that it can expect us to call the GetWorld method that is in the world object and it will return the string "World". So now when we use this object later it will have a method implemented that will return a string.
In this section of code is where we start USING our mock objects to write our test.
Person p = new Person()
string saying = p.SayHello(world);
Here we create an instance of our person class that is going to call its method SayHello and pass it that mock world object we create above as if it a real and fully created world object.
Assert.AreEqual("Hello World", saying);
This is just a normal assertion that we do for our test.
Making the test Compile
At this point if you were to try and compile it wouldn't so we will implement the code to make it compile. Lets start with the IWorld interface.
That is all you need for the IWorld interface. And that is all you will need TOTAL for the whole example for IWorld. Next is the Person Class.
The thing to notice about this piece of code is that for our parameter we are using IWorld as the type and not World since we don't have a world object yet, but we know that we are going to implement it later. Later the world object will inherit from the IWorld interface so the method will know what to do.
So now it should compile and the test should fail. This is good.
Making the test Pass
All that we need to do to make the test pass is to add change line of code now.
With this code it takes the object that it was passed and uses it as if it where a regular a real object, but it was created as a mock object in our test. The great thing is that since we created the mock object and gave it its mock functionality we can implement code to USE that functionality even though it really doesn't exist YET.
To drive home the point on my own and test further I went ahead and created a test using a real world object and a world object. It worked like a charm. Those are below.
Real Object Test
I hoped that this helped to give you an understanding of mock objects and how to use Rhino Mocks to use mock objects. I am starting to like mock objects the more I read about them mostly because I can not worry about the database code itself until last, as I don't enjoy it, and can start to work on the application itself and create a layer that is calling mock objects to retrieve data. Then later turn those mock objects into a real data access layer and I am set to go.
Please feel free to leave any comments or criticisms the more the merrier.