Search code examples
c#mockingrhino-mocks

Why RhinoMocks obligates redefining ToString() explicitly in order to be able setting expectations on it?


I'm trying to mock ToString() call on my custom object. I've created a mock for the interface and setting expectation on ToString() call

interface ICustomObject
{
}

var customObjectMock = MockRepository.GenerateMock<ICustomObject>();
var fakeDump = Guid.NewGuid().ToString();
customObjectMock.Expect(c => c.ToString()).Return(fakeDump).Repeat.Any();

Whilst test run I got run time exception saying:

System.InvalidOperationException : Invalid call, the last call has been used or no call has been made (make sure that you are calling a virtual (C#).

Well-known error, but why I got it considering that ToString() is virtual?

And more interesting - I've worked it around simply by defining ToString() explicitly in the interface:

interface ICustomObject
{
  // Weird! I believe such method definition in interface would be confusing
  // without a special remark comment saying that this method is redefined 
  // to satisfy RhinoMocks (perhaps Reflection?)
  string ToString();
}

After this RM allows setting expectations on ToString().

Just wondering why RinoMocks obligates me redefine standard virtual Object.ToString()? Perhaps RM does not consider such standard methods which available for each Framework's object and obligates redefining all methods/properties expl;icitly in order to be able setting expectations?


Solution

  • Interfaces are not objects.

    Although you can call ToString() on an interface implicitly, the assumption is that there exists some object that implements your interface, and therefore provides an implementation of ToString() implicitly.

    Since you don't provide an implementation of your interface, there is nothing to "hook" the ToString() method, and apparently RhinoMocks figures it doesn't make much sense to test a method that doesn't actually exist.