Many developers I talk with struggle with understanding the difference between mocks and stubs. They're both test doubles, objects that stand in for the real objects in test scenarios, what's the difference, and why does it matter?
The clearest explanation I've come across was written by Russ Olsen:
"A mock is a stub with an attitude. Along with knowing what canned responses to return, a mock also knows which method should be called and with what arguments. Critically, a disappointed mock will fail the test. Thus, while a stub is there purely to get the test to work, a mock is an active participant in the test, watching how it is treated and failing the test if it doesn't like what it sees."
Ok, so now that the difference between the two is clear, let's consider the situations where you might use one instead of the other. In her excellent book Practical Object-Oriented Design in Ruby Sandi Metz draws a distinction between two types of public methods that an object can have. There are "command" methods, which you use to tell the object to do something, and "query" methods, where you ask a question of the object. Take a look at a method on one of your objects. Is it clear which bucket it falls into? Do you have query methods that also cause something to happen. Hmm?
Her talk "Magic Tricks of Testing" provides a nice diagram that outlines her suggested usage.
All good, right?
Wrong. This is where things get tricky and smart, experienced people disagree.
If you ask a question of another object (query), the fact that you asked the question isn't an important part of its interaction with the other object, rather it's simply a way for the object-under-test to get the information it needs. However, if you are sending another object a message to do something (command), that interaction is typically important; you want to ensure that it actually happens. For example, if adding a new user to your system should send them an email, you care a lot that the Mailer object was sent a "sendwelcomeemail" message as part of the process.
Heather: "My friend keeps trying to explain to me mocking and stubbing and I don't get it. Can you explain to me? Do you get it?"
at 39:45 Sam talks about how and why he is opposed to stubbing collaborator objects in tests. Related to testing-concept-overmocking
mocks-vs-stubs#avdi-only-reason-to-mock1 2 3 "I'll also point out that as far as I'm concerned, the only... and I mean only reason I use mocks is to guide design during TDD. If I'm not writing tests first, there is very little point writing mocks. I believe I am consistent with the authors of GOOS (and inventors/popularizers of mocking) in this view." - Avdi Grimm somewhere on parley, I believe. mocks-vs-stubs#avdi-only-reason-to-mock1 2 3
Ryan Davis, the guy behind Minitest, said he doesn't like mocks talk-minitest-insights
At 34:00 Mock as a tool of last resort. Use when dealing with third-party APIs and you have no other choice, for example.
blog-post-the-flawed-theory-behind-unit-testing
blog-post-on-mocks-and-mockist-testing
talk-stop-mocking-start-testing-google-code-devs