The framework on which I predominately work on has used a “nightly build” script for longer than I care to recall. While the new cool kids on the block have turned to techniques such as continuous integration, we still rely on the build “once-a-day” technique, or manually kick off the process when required.
Way back when we established our build script, one of the developers created a testing framework with which we could perform unit testing. It was no jUnit, but it performed a similar role. Our team wrote some unit tests in a slightly less than committed manner and we felt good about the whole process…
That trusty in-house utility has served us well over the years and we still add unit tests to it, but the whole concept of unit-testing has matured a vast amount from where it was when we originally set off along that path. Realistically, some of our unit-tests would more accurately be described of as integration tests – that is, they are testing the interaction of two real classes. This isn’t a problem in itself, but it is not an area that unit testing is meant to be testing…
My current “side project” (read “train-time project”) has therefore been to change our unit-testing application over to an xUnit framework. I could have left the legacy framework as part of the build script and built a second testing framework for all new test-cases, but fortunately the underlying interfaces that drive the xUnit implementation are similar enough to allow relatively painless migration of our existing tests into the new framework.
With the existing test-cases migrated, I turned my attention to the development of new test-cases. Not wishing to repeat the mistakes of yester-year, I did a little research on “mock objects”. As one presentation suggested, I googled “mocks aren’t stubs”. At this point in time, it is safe to say I am not an expert in writing unit-tests. I have done them, I can see their worth and I’ve no doubt it doesn’t take a lot to get competent at writing them, but I’m still learning.
So as a really rough approximation of what the mock objects can do for you: They allow you to exactly define what things you are expecting the mock object to be used for in your unit-test. How many times a function of the mock object is used, what parameters it will be called with and what return values it should give. This helps give you an extra set of conditions by which you can verify that your code is correct.
One thing that strikes me as “odd” about this level of checking is how you are ever meant to change your code again without needing to modify the unit test. As the verification of running your unit test includes specifying exactly how your code interacts with other objects, it would seem to limit the changes you can make. Maybe that’s the point! I’ll tell you more, when I work it out!