Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

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

About James Kovacs

James Kovacs is a Technical Evangelist for JetBrains. He is passionate in sharing his knowledge about OO, SOLID, TDD/BDD, testing, object-relational mapping, dependency injection, refactoring, continuous integration, and related techniques. He blogs on CodeBetter.com as well as his own blog, is a technical contributor for Pluralsight, writes articles for MSDN Magazine and CoDe Magazine, and is a frequent speaker at conferences and user groups. He is the creator of psake, a PowerShell-based build automation tool, intended to save developers from XML Hell. James is the Ruby Track Chair for DevTeach, one of Canada’s largest independent developer conferences. He received his Bachelors degree from the University of Toronto and his Masters degree from Harvard University.
This entry was posted in .NET, Agile. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Konstantin

    Thank you for article!

  • Anonymous

    Sorry for the difficulty in reading the code. It is a post from a few years ago and the blog theme has changed since them, thus upsetting the formatting. I’ve changed the code to hopefully be more legible.

    As for using var, that’s a matter of personal preference. I don’t find that explicitly specifying the variable type twice adds to readability. (Once for the variable type and again when creating the mock on the same line.) Some people like using var, others don’t. We’ll have to agree to disagree on this point.

    As for not clarifying, I’m sorry if you didn’t understand my point. This is part of a larger conversation (see links) that happened two years ago.

  • Abc

    Clap…clap…clap…

    First off, fix the code so I can read it. Why is the article in this tiny little column and why does the code extend out of the column and run under the ad to the right? And why is it italicized in that impossible to read font?

    Second, you are abusing the var keyword. Everything doesn’t have to be declared as var. Code readability should take precedence over 3 extra seconds of typing.

    Third, this explanation did nothing to further my understanding of the difference between mocks and stubs. You dedicate two sentences to the actual difference between the two and it still didn’t clarify anything.

  • http://www.jameskovacs.com james.kovacs

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

  • Ian Cooper

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

    http://xunitpatterns.com/Test%20Double.html

  • http://jaychapman.blogspot.com John Chapman

    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.

  • http://codebetter.com/blogs/aaron.jensen/ Aaron Jensen

    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.