XpdWiki

FrontPage
RecentChanges
XtC
FindPage
PageIndex
XpApprentices

Set your name in
UserPreferences

Edit this page

Referenced by
MockObjects




JSPWiki v2.0.52


RonJefferiesOnMockObjects


The original version of the paper that documents MockObjects can be found at: http://www.sidewize.com/company/mockobjects.pdf (this paper is no longer available at http://www.connextra.com/site/all_about_us/xp.htm).


Ron Jefferies' view on Mock/Stub Objects. (From the XP mailing list 19 Sept 2000):

Last week, I was helping Bob Koss with a seminar he's working on. He was trying to talk about the use of stubs in testing. We kept coming back to the fact that we wouldn't do it. We chatted with Kent and others. Here's where I wound up:

I would use stub-type objects in testing if the tests ran horribly slowly without them. For example, accessing a database repeatedly, or accessing URLs.

I would use stub-type objects in testing if the real objects were very difficult to set up. But first, I would explore why the real objects were difficult to set up.

Stubs and Mocks introduce a new kind of potential error into the mix. When we write the real thing and the stub, we are responsible for making the semantics of the two interfaces the same. For a simple example, imagine a root stub where we tested that root 4 = 2 and root 9 = 3, and a real root routine where we tested root 8 = 2 and root 27 = 3. Both these tests run in good faith. It follows, of course, that the tests for the stub must be the same as those for the real object. In that case, why not use the real object in the rest of the tests?

My conclusion: avoid them when we can. And we usually can.

Ron Jeffries


While Ron raises a good point - the whole point of a MockObject is that it is trivially simple to set preloaded state and to set expectations on its interactions with the model (in fact it is these refactored assertions that are profoundly interesting). In almost a years worth of development at Connextra I have never noticed us suffering from the problem Ron mentions. This smacks of "try it before you comment on it" - and while I always respect what Ron has to say in this case I feel he is commenting on technique he isn't using.

I am also concerned about the example mentioned above - that doesn't look like a MockObject to me - what expectations are being set on this root object, or what values are being preloaded into it? This does not follow the format we specified in our paper. I could imagine a RootCalculator? mock object where you specified it should cause an overflow error or something of this type. In this case the test would look something like:

myMockRootCalculator.setOverflowError(true);

try { myModel.calculateOptimumVelocity(myMockRootCalculator); assert("Should get model exception"); } catch (ModelCalculationException?? ex) { assert("Model exception expected",true); }

This examples just checks for an exception, however in many circumstances there is an interaction with another model object, and again you would provide a mock object and set an expectation either that object is not called, or that an error condition is passed on eg.

myMockRootCalculator.setOverflowError(true); myMockWorkflowReporter.setExpectedProceedCalls(0); myMockWorkflowReporter.setExpectedError(ModelCalculationException);

try { myModel.calculateOptimumVelocity (myMockRootCalculator,myMockWorkflowReporter); ....

I think these tests prove to be extremely readable and they clearly communicate what is supposed to happen. If we find ourselves putting logic in a Mock we always question what is wrong (as we are duplicated code that is probably already in the model) and like Ron we look for an alternative solution -- TimM

I agree with Tim, and the above example is almost there. What we'd be trying to test in this case would be that the exception is handled in the appropriate way, (not that it's thrown as we're forcing it to be thrown). And that is the point, we don't have to think of values that will make the calculator overflow, we simply make the calculator overflow.

myMockRootCalculator.setOverflowError(true); myMockWorkflowReporter.setExpectedProceedCalls(0); myMockWorkflowReporter.setExpectedError(ModelCalculationException);

Result result = myModel.calculateOptimumVelocity (myMockRootCalculator,myMockWorkflowReporter); assert(result.isAnError());

It's not the overflowing that we'd be testing in this case, its what happens when it overflows. --OliBye³host³³date³February 2, 2001³agent³Mozilla/4.75 en? (X11; U; Linux 2.2.14-5.0 i686)³RonJefferiesOnMockObjects


Edit this page   More info...   Attach file...
This page last changed on 02-Feb-2001 18:55:00 GMT by unknown.