.net – Rhino Mocks stubs and mocks are only good for interfaces

mockingnetrhino-mocksstubbingunit testing

Is it correct that Rhino Mocks stubs and mocks are only good for interfaces, not concrete classes? I spent quite a time trying to make this piece of code working. I did not expect the stubbed pubSubClient to always call Send method from the class. That method has some dependencies and throws exception.

[Test]
public void Test01()
{
    PubSubMessage psm = new PubSubMessage(); 
    var pubSubClient = MockRepository.GenerateStub<PubSubClient>();
    pubSubClient.Stub(x => x.Send(psm)).IgnoreArguments().Return(null);
    // actual PubSubClient Send method throws exception
    // the rest of the test is skipped...
}

However, when I have extracted the interface and run the same test with IPubSubClient, it seems to be working as expected.

Does it mean that I have to extract the interface for every class I want to mock/stub with Rhino? Or I am missing something, technically or conceptually?

UPDATE: OK, It seems I figured out what part I was missing:
Rhino Mocks cannot intercept calls to non-virtual methods. So, I guess I have either use interfaces or make every method on the concrete class virtual. Please correct me if there's another option.

Best Answer

Bryan's answer of using partial mocks is incorrect. That's not what partial mocks are for.

Jon Erickson's answer is mostly correct: Rhino Mocks and Moq can't intercept non-virtual calls, nor can they intercept static methods or properties. That means you can't fake the following:

DateTime.Now; // static property, can't fake static property
someClass.SomeNonVirtualMethod(); // can't fake non-virtual method
sealedClass.Foo(); // can't fake anything on sealed classes
Utilities.SomeStaticMethod(); // can't fake static methods
someList.Any(); // can't fake extension methods like Linq's .Any()

TypeMock can fake these, as Jon mentioned.

It should be noted there is an additional mocking framework that can intercept all calls: the Microsoft Moles framework. It works the same way TypeMock does, it uses the .NET profiler API to intercept calls.

Moles is free (for now). It's also beta. Moles only only works with Microsoft Pex tools. And its API is clearly inferior to TypeMock's refined, elegant API.

Related Topic