From: Tim M. <tim...@po...> - 2003-04-17 01:17:53
|
Hi Vincent - thanks for chipping in, it was on the ToDo list to catch up with you and see how the changes would impact you as well. (If anyone else is using it - please speak up as well). Basically the library is pretty similar to before however when using it when working with e2x i noticed that the TDD experience wasn't as good as it should be - the use of a separate CallSequence to order calls or have multiple calls to the same method wasn't very intuitive. Also the error messages that you got back when things failed were not easy to interpit. I worked with Nat and then Steve to get something that seems to satisfy everyone so far. I ported the e2x codebase in about an hour - and some of that time were actually flaws in tests that the old library sort of covered up (some of these were mocks expecting other mocks as parameters, so you might not even experience this. It would be really good if you could port to the new one (I still shudder from my Connextra experience of the old mock library being so diverged we never were able to go back). The following is a fragment of how you would have written a simple servlet test: public void testDoGetOldStyle() throws ServletException, IOException { Mock mockHttpServletResponse = new Mock(HttpServletResponse.class); Mock mockHttpServletRequest = new Mock(HttpServletRequest.class); CallSequence params = new CallSequence(); params.expectAndReturn( new Constraint[] { C.eq("body") }, "this is the body" ); params.expectAndReturn( new Constraint[] { C.eq("subject") }, "mail from tim" ); params.expectAndReturn( new Constraint[] { C.eq("recipients") }, new String[] { "nat...@b1...", "st...@m3..." } ); mockHttpServletRequest.expect( "getParameter", params ); SimpleServlet aServlet = new SimpleServlet(); aServlet.doGet((HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy()); mockHttpServletRequest.verify(); mockHttpServletResponse.verify(); } The following is how you would now write it (with a few extra features and examples shown as well): public void testDoGetOldStyle() throws ServletException, IOException { Mock mockTimer = new Mock(Timer.class); Mock mockHttpServletResponse = new OrderedMock(HttpServletResponse.class, "response"); Mock mockHttpServletRequest = new Mock(HttpServletRequest.class); mockHttpServletRequest.matchAndReturn( "getParameter", C.args(C.eq("browser-identifier")), "MSIE-5.0" ); mockHttpServletRequest.expectAndReturn( "getParameter", "subject", "Mail Subject" ); mockHttpServletRequest.expectAndReturn( "getParameter", C.args(C.eq("body")), "Mail Body" ); mockTimer.expectAndReturn("getTime", 10000); mockTimer.expectAndReturn("getTime", 20000); final PrintWriter contentWriter = new PrintWriter(new StringWriter()); mockHttpServletResponse.expect( "setContentType", "text/html"); mockHttpServletResponse.expectAndReturn( "getWriter", C.args(), contentWriter ); // proposed arbitrary odering implementation // CallMatch m1 = mockHttpServletResponse.expect( "setContentType", "text/html"); // CallMatch m2 = mockHttpServletResponse.expectAndReturn( "getWriter", contentWriter ); // m1.expectBefore(m2); SimpleServlet aServlet = new SimpleServlet((Timer)mockTimer.proxy()); aServlet.doGet((HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy()); mockHttpServletRequest.verify(); mockHttpServletResponse.verify(); mockTimer.verify(); } Basically to port: references to CallSequence will break (its now an interenal object that shouldn't be used). Take each of the expectAndReturn lines and just run them against a Mock (like we with the mockHttpServletRequest) and then remove the sequence. Mock.expect doesn't take a calls object - its like expectVoid (see below). You can choose between Mock and OrderedMock - to decide if you want set like (any order calls) or list like behavior. They both have expect, expectAndReturn, expectAndThrow style methods, along with match... methods (this latter is for returning a value for a method signature that matches). YOUR OPINION? For void methods, we have used expect("aVoidMethod"... in the old library this was called expectVoid(... There is a deprecated version in there to help porting - whats your opinion on the rename to just expect? (The issue is - for true consistency it should be ExpectAndVoid - but if you aren't expecting any return value or exception why put that in the name? Shorter seems better?). FUTURE: Error messages are much better - they still can be improved. Mocks that takes mocks as expect parameters give strange errors if you forget to use mock.proxy (we could overload this and do the .proxy automatically?) You can see the example of how we might do call odering for better precision C.ANY_ARGS is currently removed - use C.anyArgs(argCount) - becuase of the proper signature overloading using null is a problematic. ANY_ARGS should be a proper object not an array. It may be useful to have a CallSubSetMock and a CallSubListMock (which probably means OrderedMock should be renamed to CallListMock) Hope this helps. Tim -----Original Message----- From: Vincent Massol [mailto:vm...@pi...] Sent: 16 April 2003 18:45 To: 'Tim Mackinnon'; 'Mockobjects-Java-Dev' Subject: RE: [MO-java-dev] Java Dynamic Mocks - going to Head? Hi Tim, I have been using the DynaMocks for a while now on several projects (using CVS builds as there were no releases). I have not been following very closely the changes you brought to the experimental branch. Are the new DynaMocks very different from the other ones? How easy is it for me to migrate? I guess I should take a look but I am very much in a hurry and any help will be greatly appreciated. Maybe some docs about how to use the new dyna mocks, etc? Thanks -Vincent > -----Original Message----- > From: moc...@li... > [mailto:moc...@li...] On Behalf Of Tim > Mackinnon > Sent: 16 April 2003 10:23 > To: Mockobjects-Java-Dev > Subject: [MO-java-dev] Java Dynamic Mocks - going to Head? > > Guys - > > First of all, sorry for missing Xtc - I've got the dynamic bug and want to > see the library in a state that it can be used in many projects. I think > its > important to convey the power and simplicity of mocks (we all know this, > but > there are so many bad examples out there...). > > Anyway - I tried using the branch in the e2x codebase and as always, on a > real project there are often little subtleties that catch you out. As John > Nolan was around working on his own little pet project we bounced ideas of > each other to get things done. > > Anyway - the library is working out quite well now and we should consider > rolling it in to the head stream soom! (Maybe a day or two more of "in > usage" testing, and comments from anyone else who is interested - but to > be > honest making it available in the head should allow greater changes). > > Here are some points: > > 1) To test the dynamic stuff, we used Traditional Mocks - it became a pain > hand coding them, especially on larger interfaces, so we took the decision > to use MockMaker. This worked well, however their are some ReturnXXX > objects > that it uses that should be in the base library. In the branch I have just > put them in - however they duplicate some existing functionality. I propse > we resolve this duplication in a second pass as it requires updates to > code > that mockmaker generates. Having the additional duplication allows an > exisiting generated mock to be updated by simply removing 3 import lines. > To > get a full solution we need to get all the tools running on a single > platform - and you use the right one for the right job. > > 2) The Callable interface has a "matches" method, this doesn't feel right > for all callables, its required for CallBag to operate - others don't need > it. This should be removed and implemented as a private decoration for > CallBag. > > 3) Steve's exellent suggestion of having: > > Callable c1 = mock.expect("setContentType".....) > Callable c2 = mock.expect("getWriter".....) > c1.expectBefore(c2) > > has not yet been implemented. This should work quite easily, but the focus > has been on UnorderdMock and OrderedMock. > > 4) As you can use mocks as expected values themselves - there was some > ugliness with the proxies needing to detect equality of mocks (you can see > this in the invoke method). I'm not sure if there is a better way to do > this. > > 5) I think Mocks should probably register with something so that we can do > the Verifier.verify on both instance variables and local variables in a > test. I am still seeing lots of accidently unverified mocks > > Overall the sample test case is looking very good (I have included it > again > below). How does everyone feel going ahead with a merge (I can probably > get > Chris Cottee to help me merge it in at e2x)? > > Tim > > public void testDoGetNew() throws ServletException, IOException { > Mock mockHttpServletResponse = new > OrderedMock(HttpServletResponse.class, > "response"); > Mock mockHttpServletRequest = new > Mock(HttpServletRequest.class); > > mockHttpServletRequest.matchAndReturn( "getParameter", > C.args(C.eq("browser-identifier")), "MSIE-5.0" ); > mockHttpServletRequest.expectAndReturn( "getParameter", > "subject", "Mail > Subject" ); > // Alternative syntax > mockHttpServletRequest.expectAndReturn( "getParameter", > C.args(C.eq("body")), "Mail Body" ); > > final PrintWriter contentWriter = new PrintWriter(new > StringWriter()); > > mockHttpServletResponse.expect( "setContentType", > "text/html"); > mockHttpServletResponse.expectAndReturn( "getWriter", > contentWriter ); > > // Still to do, instead of making response an OrderedMock > // CallMatch m1 = mockHttpServletResponse.expect( > "setContentType", > "text/html"); > // CallMatch m2 = mockHttpServletResponse.expectAndReturn( > "getWriter", > C.args(), contentWriter ); > // m1.expectBefore(m2); > > SimpleServlet aServlet = new SimpleServlet(); > aServlet.doGet((HttpServletRequest) > mockHttpServletRequest.proxy(), > (HttpServletResponse) mockHttpServletResponse.proxy()); > > mockHttpServletRequest.verify(); > mockHttpServletResponse.verify(); > } > --- > Outgoing mail is certified Virus Free. > Checked by AVG anti-virus system (http://www.grisoft.com). > Version: 6.0.467 / Virus Database: 266 - Release Date: 01/04/2003 > > > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Mockobjects-java-dev mailing list > Moc...@li... > https://lists.sourceforge.net/lists/listinfo/mockobjects-java-dev --- Incoming mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.467 / Virus Database: 266 - Release Date: 01/04/2003 --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.467 / Virus Database: 266 - Release Date: 01/04/2003 |