A while ago I read the Mocks Aren\'t Stubs article by Martin Fowler and I must admit I\'m a bit scared of external dependencies with regards to added complexity so I would like
Read Luke Kanies' discussion of exactly this question in this blog post. He references a post from Jay Fields which even suggests that using [a equivalent to ruby's/mocha's] stub_everything is preferrable to make the tests more robust. To quote Fields' final words: "Mocha makes it as easy to define a mock as it is to define a stub, but that doesn't mean you should always prefer mocks. In fact, I generally prefer stubs and use mocks when necessary."
It just depends on what type of testing you are doing. If you are doing behavior based testing you might want a dynamic mock so you can verify that some interaction with your dependancy occurs. But if you are doing state based testing you might want a stub so you verify values/etc
For example, in the below test you notice that I stub out the view so I can verify a property value is set (state based testing). I then create a dynamic mock of the service class so I can make sure a specific method gets called during the test (interaction / behavior based testing).
<TestMethod()> _
Public Sub Should_Populate_Products_List_OnViewLoad_When_PostBack_Is_False()
mMockery = New MockRepository()
mView = DirectCast(mMockery.Stub(Of IProductView)(), IProductView)
mProductService = DirectCast(mMockery.DynamicMock(Of IProductService)(), IProductService)
mPresenter = New ProductPresenter(mView, mProductService)
Dim ProductList As New List(Of Product)()
ProductList.Add(New Product())
Using mMockery.Record()
SetupResult.For(mView.PageIsPostBack).Return(False)
Expect.Call(mProductService.GetProducts()).Return(ProductList).Repeat.Once()
End Using
Using mMockery.Playback()
mPresenter.OnViewLoad()
End Using
'Verify that we hit the service dependency during the method when postback is false
Assert.AreEqual(1, mView.Products.Count)
mMockery.VerifyAll()
End Sub
As the mantra goes 'Go with the simplest thing that can possibly work.'
Avoid using mocks always because they make tests brittle. Your tests now have intricate knowledge of the methods called by the implementation, if the mocked interface or your implementation changes... your tests break. This is bad coz you'll spend additional time getting your tests to run instead of just getting your SUT to run. Tests should not be inappropriately intimate with the implementation.
So use your best judgment.. I prefer mocks when it'll help save me writing-updating a fake class with n>>3 methods.
Update Epilogue/Deliberation:
(Thanks to Toran Billups for example of a mockist test. See below)
Hi Doug, Well I think we've transcended into another holy war - Classic TDDers vs Mockist TDDers. I think I'm belong to the former.
Never mind Statist vs. Interaction. Think about the Roles and Relationships. If an object collaborates with a neighbour to get its job done, then that relationship (as expressed in an interface) is a candidate for testing using mocks. If an object is a simple value object with a bit of behaviour, then test it directly. I can't see the point of writing mocks (or even stubs) by hand. That's how we all started and refactored away from that.
For a longer discussion, consider taking a look at http://www.mockobjects.com/book
I generally prefer to use mocks because of Expectations. When you call a method on a stub that returns a value, it typically just gives you back a value. But when you call a method on a mock, not only does it return a value, it also enforces the expectation that you set up that the method was even called in the first place. In other words, if you set up an expectation and then don't call that method, an exception gets thrown. When you set an expectation, you are essentially saying "If this method doesn't get called, something went wrong." And the opposite is true, if you call a method on a mock and did not set an expectation, it will throw an exception, essentially saying "Hey, what are you doing calling this method when you didn't expect it."
Sometimes you don't want expectations on every method you're calling, so some mocking frameworks will allow "partial" mocks that are like mock/stub hybrids, in that only the expectations you set are enforced, and every other method call is treated more like a stub in that it just returns a value.
One valid place to use stubs I can think of off the top, though, is when you are introducing testing into legacy code. Sometimes it's just easier to make a stub by subclassing the class you are testing than refactoring everything to make mocking easy or even possible.
And to this...
Avoid using mocks always because they make tests brittle. Your tests now have intricate knowledge of the methods called by the implementation, if the mocked interface changes... your tests break. So use your best judgment..<
...I say if my interface changes, my tests had better break. Because the whole point of unit tests is that they accurately test my code as it exists right now.
It's best to use a combination, and you'll have to use your own judgement. Here's the guidelines I use:
The second kind of mock is a sort of necessary evil. Really what's going on here is that whether you use a stub or a mock, in some cases you have to couple to your code more than you'd like. When that happens, it's better to use a mock than a stub only because you'll know when that coupling breaks and your code is no longer written the way your test thought it would be. It's probably best to leave a comment in your test when you do this so that whoever breaks it knows that their code isn't wrong, the test is.
And again, this is a code smell and a last resort. If you find you need to do this often, try rethinking the way you write your tests.