June 14, 2007

Fake Objects in RhinoMocks

It seems Ayende is keeping busy with Rhino Mocks (aside from blogging 5 times per day). He has now implemented Fake Objects (called a Stub in Rhino Mocks).

First to give some background, there is a difference between a Mocked object and a Fake object.
With Fake Objects, think of a simple class with only properties containing both getters and setters. You can set any property to a value, but the fake object really doesn't care what happens to it. If you set a property to a value, it returns that value until that value is set to something else. I am not sure, but I don't thing you can tell a Fake object function what to return. So if you need that, you should probably use the Mock Object -- read on.

With Mock Objects, they are much more complex beasts. You must warn the Mocked object for every call made to the object, and tell the Mocked Object what to return. One nice thing about Mocked Objects is that functions can be mocked.

Each object, Fake and Mock, has their place in a testing scheme, so it is important to know the difference. If you need simple returns with getters and setters, and don't care if something does or doesn't get called use a Fake Object. Otherwise use a Mock Object.

Anyway, if I have an interface that looks like this:

   1:  public interface IMyObject
   2:  {
   3:        public string MyProperty1 { get; set; }
   4:        public string MyProperty2 { get; set; }
   5:  }

I can create and use a Fake Object for it like this:
   1:  IMyObject o = MockRepository.GenerateStub<imyobject>();
   2:  o.MyProperty1 = "Hi";
   3:  o.MyProperty2 = "There";   
   4:  Assert.AreEqual("Hi", o.MyProperty1);
   5:  Assert.AreEqual("There", o.MyProperty2);
as apposed to creating and using a Mock Object
   1:  MockRepository mock = new MockRepository();
   2:  IMyObject o =  mock.CreateMock<IMyObject>();
   3:  Expect.Call(o.MyProperty1).Return("Hi");
   4:  Expect.Call(o.MyProperty2).Return("There");
   5:  mock.ReplayAll();
   6:  Assert.AreEqual("Hi", o.MyProperty1);
   7:  Assert.AreEqual("There", o.MyProperty1);
   8:  mock.VerifyAll();
As you can see, there is nothing special to using a Fake Object, just set and get the properties like normal. Whereas with Mock Object you have to call Expect.Call for everything that gets touched.

Have fun.

No comments: