A friend, having recently upgraded to Rhino Mocks 3.5, expressed his confusion regarding when to use mocks vs. stubs. He had read Martin Fowler’s Mocks Aren’t Stubs (recommended), but was still confused with how to actually decide whether to use a mock or a stub in practice. (For a pictorial overview, check out Jeff Atwood slightly NSFW photo montage of dummies, fakes, stubs, and mocks.) I thought I’d share my response which cleared up the confusion for my friend…
It’s easy to get confused. Basically, mocks specify expectation. Stubs are just stand-in objects that return whatever you give them. For example, if you were testing that invoices over $10,000 required a digital signature…
// Arrange var signature = DigitalSignature.Null; var invoice = MockRepository.GenerateStub<IInvoice>(); invoice.Amount = new Money(10001M); invoice.Signature = signature; var signatureVerifier = MockRepository.GenerateMock<ISignatureVerifier>(); signatureVerifier.Expect(v => v.Verify(signature)).Return(false); var invoiceRepository = MockRepository.GenerateMock<IInvoiceRepository>(); var accountsPayable = new AccountsPayable(signatureVerifier, invoiceRepository); // Act accountsPayable.Receive(invoice); // Assert invoiceRepository.AssertWasNotCalled(r => r.Insert(invoice)); signatureVerifier.VerifyAllExpectations();
I don’t have a real invoice. It’s a proxy generated by Rhino Mocks using Castle DynamicProxy. You just set/get values on the properties. Generally I use the real object, but stubs can be handy if the real objects are complex to set up. (Then again, I would consider using an ObjectMother first.)
Mocks on the other hand act as probes to detect behaviour. We are detecting whether the invoice was inserted into the database without requiring an actual database. We are also expecting the SignatureVerifier to be called and specifying its return value.
Now the confusing part… You can stub out methods on mocks too. If you don’t care whether a method/property on a mock is called (by you do care about other aspects of the mock), you can stub out just that part.
You cannot however call Expect or Stub on stubs.
UPDATE: I’m including my comments inline as they respond to important points raised by Aaron and John in the comments and many readers don’t bother looking through comments.
@Aaron Jensen – As Aaron points out in the comments, you are really mocking or stubbing a method or property, rather than an object. The object is just a dynamically generated proxy to intercept these calls and relay them back to Rhino Mocks. Whether it’s a mock/stub/dummy/fake doesn’t matter.
Like Aaron, I prefer AssertWasCalled/AssertWasNotCalled. I only use Expect/Verify if the API requires me to supply return values from a method/property as shown above.
I also have to agree that Rhino Mocks, while a great mocking framework that I use everyday, is showing its age. It has at least 3 different mocking syntaxes (one of which I contributed), which increases the confusion. It’s powerful and flexible, but maybe a bit too much. Rhino Mocks vNext would likely benefit from deprecating all but the AAA syntax (the one borrowed from Moq) and doing some house-cleaning on the API. I haven’t given Moq an honest try since its initial release so I can’t comment on it.
@John Chapman – Thanks for the correction. I’ve had Rhino Mocks throw an exception when calling Expect/Stub on a stub. I assumed it was expected behaviour that these methods failed for stubs, but it looks like a bug. (The failure in question was part of an overly complex test and I can’t repro the issue in a simple test right now. Switching from stub to mock did fix the issue though.) stub.Stub() is useful for read-only properties, but generally I prefer getting/setting stub.Property directly. Still stub.Expect() and stub.AssertWasCalled() seems deeply wrong to me.