It's a litlte easy to get carried away with mocking when you first start doing it in conjuction with unit tests. Mocks are unbelivably flexible/powerful. However, to get the most out of them, you really need to be able to inject your mock into the class you're testing. Conincidentaly trying to leverage mocks in your code will lead you to the first tangible benefit of unit testing - you'll notice how tightly coupled your code is (i.e., impossible to test) and learn a wonderful aresenal of strategies to help you write better code.
There comes a point though where injection just doesn't make a whole lot of sense for anything _but_ testing and even then the value might not be that evident. Let's see how we can use RhinoMock's Partials to solve the problem. Take for example an LoginHttpHandler that looks something like:
public void ProcessRequest(NameValueCollection parameters)
{
string userName = parameters["username"];
string password = parameters["password"];
User user = User.CreateFromCredentials(userName, password);
//do something with our user
}
This code is impossible to unit test because the call to User.CreateFromCredentials can't be mocked/faked/anything. The best we can do is mock whatever dependencies User.CreateFromCredentials has - but that's just a nightmare not worth exposing ourselves to.
What we can do is use a partial instead of a mock. A mock is a dumb object that only records expectations and actuals. A partial on the other hand exposes all of the behavior of the class we've created a partial for - except those we've explicitly set expecations on. For example, if we rewrite the above code as:
public void ProcessRequest(NameValueCollection parameters){
string userName = parameters["username"];
string password = parameters["password"];
User user = GetUser(userName, password);
//do something with our user
}
public virtual User GetUser(string userName, string password)
{
return User.CreateFromCredentials(userName, password);
}
We can use a partial to write a useful unit test (well, there isn't much to test for, but you get the idea):
[Test]
public void LoginHandlerInteractsWithUser()
{
MockRepository mocks = new MockRepository();
LoginHttpHandler handler = mocks.PartialMock();
User fakeUser = new User();
NameValueCollection nvc = new NameValueCollection();
nvc.Add("userName", "un");
nvc.Add("password", "pass");
using (mocks.Record())
{
Expect.Call(handler.GetUser(nvc["userName"], nvc["password"])).Return(fakeUser);
}
using (mocks.Playback())
{
handler.ProcessRequest(nvc);
}
mocks.VerifyAll();
}
We create a partial of our LoginHttpHandler which behaves exactly like a new instance of it - except for those methods (like GetUser) which we've set an expectation on. Just like with a mock, if ProcessRequest called GetUser twice, we'd have to record that call twice. Unlike a mock however, if we didn't, the 2nd call would call the real implementation of GetUser.
The only other thing to keep in mind is that the method you plan on mocking must be virtual - this allows RhinoMocks to override the method and do it's own thing (implement the record/playback logic).
In my recent trip down Java land, I actually have a hell of a problem doing this seemingly simple thing. I tried a number of mocking frameworks, eventually settling on EasyMock but the amount of work needed to set up partials was insane. If I missed something, I'd love to know about it.