From: Nat P. <nat...@b1...> - 2003-04-08 15:44:17
|
While supping a latte in a pavement cafe on Upper Street (ah, the joys of unemployment!) a particle of inspiration happened to penetrate my dense skull and hit a receptive spot within, sparking some thoughts about the new dynamic mock branch. I'm commiting them to email in case I forget them before I get a chance to implement them, and Cc'ing them to the mockobjects mailing list for review by everyone else. Firstly, I think that the "CallMocker" interface would be better renamed to "Callable", and "CallSet" would be better named "CallableSelection". Secondly, I have come to agree with your (Tim's) idea about separating the sugar methods from the composite callable classes. You're right -- it will makes the methods much easier to test. I also now think that the Mock class should *not* inherit from CallableSelection. By extending CallableSelection, Mock objects inherit the matches method, which is of no use to their clients. By separating the sugar methods from the composite implementations, and making the Mock class extend the sugar class, we get a much simpler design, make the sugar methods easier to test, remove the unnecessary matches method from the Mock class, and allow the user to choose whether a mock expects a selection or sequence of callables at construction time. A problem we had on Monday was how to make it easy for users to create composites *and* use sugar methods for those composites. The solution is for the sugar methods that create composites (expectSequence for example) to create and return a wrapper that provides sugar methods for the new composite, rather than return the composite itself. I've attached a quick UML class diagram that illustrates this. Apologies for the BDUF, but I have no easy access to CVS at the moment and so cannot implement it directly (and I would prefer to pair program it anyway -- perhaps at an XTC evening). I've called the sugar class "CallCollection", and the base interface of CallableSequence and CallableSelection, "CompositeCallable". CompositeCallable just adds the method "void add( Call call )" to the Callable interface. Use of the sugar methods would look the same as in your (Tim's) email but would always return a CallCollection rather than a CallSequence or CallSelection: Mock aMock = new Mock(HTTPServletResponse.class); CallCollection seq = aMock.expectSequence(); seq.expectVoid( "setContentType", C.args("text/html") ); CallCollection sel = seq.expectSelection(); // these headers must be set, but can be in any order sel.expectVoid("setHeader", C.args( C.eq("header1") ); sel.expectVoid("setHeader", C.args( C.eq("header2") ); sel.expectVoid("setHeader", C.args( C.eq("header3") ); // additional headers are optional sel.permitVoid("setHeader", C.args( C.IS_ANYTHING ) ); seq.expectAndReturn( "getWriter", C.args(), WRITER ); Cheers, Nat. _______________________ Dr. Nathaniel Pryce B13media Ltd. http://www.b13media.com +44 (0)7712 526 661 |