James Kovacs

Sponsors

The Lounge

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Mocks vs. Stubs

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. :)


Posted Mon, Feb 9 2009 10:38 PM by james.kovacs
Filed under: ,

[Advertisement]

Comments

Aaron Jensen wrote re: Mocks vs. Stubs
on Tue, Feb 10 2009 1:33 AM

Hey James,

Thanks posting the explanation, lots of people have trouble distinguishing this. I think most of the problems come from the fact that mocking frameworks call the objects created mocks or stubs rather than calling out the fact that we are mocking or stubbing a method on an object. What that object is is really moot.

Another thing that is often confused is that many think the Expect and Verify methods are part of the AAA syntax. Ayende himself claims they are so I can see where the confusion comes from :) In my mind, the two are artifacts of the old way of using mocks *before* AAA syntax was realized to be so important. I strongly prefer to use AssertWasCalled instead of Expect/Verify. Not only is it one method instead of two, but it actually *does* follow AAA. If you don't believe me, consider the scenario where you want to test that when you call Receive it verifies that Verify was called and Insert was called, but you want to also follow the one assert per test guideline. Expect/Verify simply does not lend itself to this.

This distinction becomes very important when doing BDD and creating many "fixtures" (or contexts) with multiple one line "tests" (or specifications).

Rhino.Mocks is a great and powerful framework, but I think the multitude of non-opinionated API options cloud guidance and create confusion. Moq is much better in this regard--it has a much lighter framework and far fewer ways to do the same thing.

John Chapman wrote re: Mocks vs. Stubs
on Tue, Feb 10 2009 10:13 AM

James,

I don't think you fully cleared up your friend's confusion. In fact I think you may be a bit confused as well.  You clearly understand the definitions of Mocks and Stubs, but you have confusion as to what Rhino Mocks does with them.

You most definitely can call Stub<> on a stub.  On top of that you can call things like AssertWasCalled() on a stub as well, almost removing the need in most cases to use a Mock.

To make matters worse the definition of a stub specifies that a stub should have repeatable behavior by default, but there is a bug in rhino mocks where by default it only repeats a stubbed behavior on a stub a single time.

Really I think it is Rhino Mocks that is causing the confusion for people.  Rhino Mocks is a fantastic product, but it has always had issues when it came to fully understanding the differences between the various pieces.

Dew Drop - February 10, 2009 | Alvin Ashcraft's Morning Dew wrote Dew Drop - February 10, 2009 | Alvin Ashcraft's Morning Dew
on Tue, Feb 10 2009 10:16 AM

Pingback from  Dew Drop - February 10, 2009 | Alvin Ashcraft's Morning Dew

DotNetShoutout wrote Mocks vs. Stubs - James Kovacs
on Tue, Feb 10 2009 11:50 AM

Thank you for submitting this cool story - Trackback from DotNetShoutout

Ian Cooper wrote re: Mocks vs. Stubs
on Tue, Feb 10 2009 1:51 PM

It's really worth reading Gerard Meszaros on this where he suggests looking at whether you need to replace an input from a depended upon component (stub or fake) or capture the output to a depended upon a component (spy or mock).

xunitpatterns.com/Test%20Double.html

igorbrejc.net » Fresh Catch For February 11th wrote igorbrejc.net &raquo; Fresh Catch For February 11th
on Wed, Feb 11 2009 7:01 AM

Pingback from  igorbrejc.net &raquo; Fresh Catch For February 11th

James Kovacs' Weblog wrote Mocks vs. Stubs
on Thu, Feb 12 2009 1:22 AM
james.kovacs wrote re: Mocks vs. Stubs
on Thu, Feb 12 2009 1:24 AM

@Aaron & @John - Updated post to respond to your comments. Thanks for the feedback.

Daniel Teng wrote Weekly links #1
on Sun, Feb 15 2009 5:01 AM

关于敏捷

FixingtheAgileEngineeringProblemblog.gdinwiddie.com/.../fixing-the-agile-en...

Add a Comment

(required)  
(optional)
(required)  
Remember Me?