From: Tim M. <tim...@po...> - 2003-04-08 01:13:05
|
Guys - The recent rash of cvs commits are an attempt by Nat and I (and Steve too) to get a version of the java dynamic mock implementation in a state that it supports the creation of simple, easily readable tests, but at the same time supports more complicated constraint based calls for the rarer cases that need something extra. The followig is a bit of a ramble (or brain dump) - but i thought its probably best to dump away so people know whats going on (and can try it out. I want to give it a spin for a few days and see how it feels to). As we all know, supporting hard coded mocks is a bit of pain (sometimes - as with the file io stuff - there isn't any simple way... although the work on NMock and rupert's team gives some other possibilities with class loader method replacements). In doing this work we generated some hard mocks and noted that we need to sort out MockMakers' reliance on things that aren't in the core library (or are, but are called something different). For clean, TDD code - dynamic mocks give a nice TDD feel if there isn't too much overhead in writing the tests. The previous implementation established the usefulness of a dynamic approach but it was a bit awkward to use in practice and fixing some of its defficiencies were tricky. The aim of this new branch is too: - make writing normal tests as easy as possible (see the acceptance test below). The discussion when with a partner should be natural with not too much initial complexity. - make failed mock tests break cleanly and clearly with good error messages (the classic library did a reasonably good job of this, but had no tests to show it) - provide a tested framework that will support modifications (e.g. eat our own dogfood) - allow support for more aesoteric<sp?> call orderings. e.g. *Sequence*Bag* Our test functional test was to write a servlet test that could look like this: public void testDoGetNew() throws ServletException, IOException { Mock mockHttpServletResponse = new Mock(HttpServletResponse.class, "response"); Mock mockHttpServletRequest = new Mock(HttpServletRequest.class); // name optional mockHttpServletRequest.expectAndReturn( "getParameter", C.args(C.eq("subject")), "Mail Subject" ); mockHttpServletRequest.expectAndReturn( "getParameter", C.args(C.eq("body")), "Mail Body" ); mockHttpServletRequest.permitAndReturn( "getParameter", C.args(C.eq("browser-identifier")), "MSIE-5.0" ); final StringWriter contentWriter = new StringWriter(); // Not yet implemented - proposed way of introducing a sequence with not to much syntax // CallSequence seq = mockHttpServletResponse.expectSequence(); // seq.expectVoid( "setContentType", C.args(C.eq("text/html")) ); // seq.expectAndReturn( "getWriter", C.args(), contentWriter ); SimpleServlet aServlet = new SimpleServlet(); aServlet.doGet( (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy()); mockHttpServletRequest.verify(); mockHttpServletResponse.verify(); } In the branch we haven't got ordered sequences working yet (it should be simple - a proposed syntax is shown. We want something that isn't too heavy wait and works will with TDD). In eclipse - to find the branch search for tags on the Mock class (e.g. tag is DynamicMockExperiment). Some notes: a mock defaults to a type of CallSet (we can't agree on this - tim thinks it has a type of CallSet). Either way, there is a primitive add method that has CallMatch and ExpectedCall objects (that decorate each other) to give the symantics we want. There is no CallSequence yet, adding it should give a CallCollection super class. We haven't yet got a SingleCall decoration to limit a CallMatch to a single invocation (again should be easy). CallSet has a DecoratorFactory so we have a hook to test the syntactic sugar for expectAndReturn (by the way - permitAndReturn is a way of stubbing without an expectation, permit because the return is based on a call that conforms to the constraints). Everything conforms to CallMocker (an awful name - can't think of a good one). Having this interface meant we could use mockmaker to generate hard mocks to allow us to test the implementation. We didn't do this soon enough (thinking it was too meta circular, but if you don't mix dynamic and hard mocks it works out well and it simplified a lot of our testing. Not all the names are correct, and some of the tests could do with a partner for Nat or I to work with to cause a cleanup (anyone up for remote pairing?) I think thats it for now. Tim --- 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 |