- Last edited October 2, 2000 |
PaulS has been applying MockObjects to the enhancements he is making to an existing in-house java suite. Initially there was no test suite, so he's been gradually introducing tests for every new piece of functionality, and every bug. 34 Tests so far, all working!
Testing an existing package is difficult as we often cannot afford to build a complete test suite first. So the approach of building a test suite as we go seems good to me (what do you think?).
So I create a Mock implementation or two to help exercise a particular object in my test case.
What if the Mock object already exists, in use with another test? Simple - I enhance it, make the tests work and refactor it to some degree (HowMuchToRefactorMockObjects? is another discussion).
What if the interaction with the Mock is different between the two tests? Its difficult to refactor. IMO this points to dual responsibility of the real class which this Mock represents. But it might just be two "views" on the same. My naturally inclination is to think about java Interfaces to separate the responsibilities/views.
I then began to think about FakeObjects?. A FakeObject? implements an interface in a minimal way to support a test. It provides base behaviour. It's not there to provide a mechanism to check the internal state like a MockObject, nor is it there to apply Demeter.
On a different track, my 3rd party library has a Widget object which is constructed with Primer. Primer has complex dependancies, so I'd rather create a simpler one. I could create a MockPrimer?, but I really need a PrimerInterface? too. Maybe I'll create a FakePrimer? here, so that I can get on to test my use of the Widget in my own domain.
I think FakeObjects? wouldn't exists if you had complete control over your code base. (See DoMockBoysDreamOfAnAllTestsPassWorld? ) but use of 3rd party libraries means this is rare.
So I now seek to use MockObjects where possible, but when an object's responsibilities get complex and that object is owned outside of my code domain, I look to create a FakeObject?.
I'm confused, I use MockObjects to dummy up the behaviour of real objects. Sometimes, I also use them to make assertions about other code. You could argue that FakeObjects? are a degenerate case of MockObjects, where you don't need the assertions. I still think you need fakes or mocks even if you have all the code, if you're going to localise your unit tests because some state is just to complicated to set up properly. Your turn. --SteveF
Yes, I think I meant fakes are degenerate mocks, without the assertions. Thanks for that observation. That's exactly the point. I could just create a MockPrimer? for my test, but I find that I've already got one that does some assertions that I don't require for this test. Instead I just want a very thin implementation. I've often found this relates nicely to the UseOfInterfacesAsParameters?.
Why would you want to write a new one if you've already got a MockPrimer?? The assertions only apply if you explcitly set up expectations about its interactions. That's the point about the MockObject pattern -- put everything together in the unit test where you can see it. If you don't set any expectations, then you get a set of fake responses anyway. We do this all the time. --SteveF
- Last edited October 2, 2000 |