From: Steve F. <st...@m3...> - 2002-10-20 15:45:56
|
Back again... It struck me that we're not really converging on this topic, partly because we don't have enough time but mainly because we're not really working against the same problems. How about the following as a process? You post a (made-up) example of a case that you want to unit-test and that you think needs a change. We'll respond and see if we can find a meaningful way around it. If not, then you win the point. I figure that this will be a reasonably lightweight mechanism for understanding each other and for pushing the dialogue along. One case at a time... Steve From: "Simon Levitt" <simon.levitt@> > I might be able to get permission to release a simple example, but even > that is going to be muddied by the use of our own Connection Pooling and > Query management/wrapper classes. > > I could knock up a simple example, but would that defeat the point? |
From: Simon L. <sim...@uk...> - 2002-10-21 16:37:53
|
On Sunday 20 October 2002 16:45, Steve Freeman wrote: > It struck me that we're not really converging on this topic, partly > because we don't have enough time but mainly because we're not really > working against the same problems.=20 [...] > Unfortunately, other than the obvious getting a Connection from a=20 Statement issue we've highlighted before I haven't come across an other=20 real examples. I've really been talking in the abstract, and how=20 MockObjects could perhaps be used outside of the ideal use only in new=20 projects written with them in mind. > You post a (made-up) example of a case that you want to unit-test and > that you think needs a change. We'll respond and see if we can find a > meaningful way around it. If not, then you win the point. > The trouble is any example I come up with quickly (and unfortunately I=20 haven't got the time to do anything else), is probably going to be easily=20 picked apart by saying that it shouldn't be written that way. StrawMan: public class DataObject { private static Statment stmt =3D =09 Global.getConnection().createStatement(); public DataObject(String name, int flags, boolean readOnlyRecord) { ... } =09 ... public static DataObject load(String id) { try { result =3D stmt.executeQuery("SELECT * FROM table WHERE id =3D " + id); if (result.next()) { obj =3D new DataObject(result.getString(1), result.getInt(3), stmt.getConnection().isReadOnly()); } } catch (SQLException e) { throw DataObjectException(e.toString()); } return obj; } } You can test the object outside of the scope of the database, but the=20 database functionality is fully encapsulated in the Object itself. The=20 point of use of the load() method doesn't even need to know that the=20 database is being used. It also isn't storing and object for the sake of=20 testing (ie. the implementation knows that a statment is associated with=20 a particular connection, therefore doesn't need to store the Connection). With the com.mockobjects.sql package as it stands (or did last time I did=20 an update) setting up this situation will cause a StackOverflowError (if=20 verify is called on the Connection. This failure is partly due to the way the sql MockObjects have been=20 written, but its the verifier that actually causes the fatal error on=20 tests. I believe the verifier should be able to detect this situation (probably=20 warning about it) and cope in a far better way. Similar situations could=20 easily be created in user developed MockObjects, if any similar hierachy=20 is created, and informing them is IMO far better than crashing. > I figure that this will be a reasonably lightweight mechanism for > understanding each other and for pushing the dialogue along. One case > at a time... > This is probably the biggest difference, I'm not looking at a specific=20 single case, I'm thinking more generally. This is a very small point, far eclipsed by the discussions we've had. Whilst I think its important, more from a perception of MockObjects point=20 of view I don't much care if its taken on board any more. Particularly as=20 we appear to be the only two concerned about it in any form. I'd much rather be spending time presenting the rationisation I've done=20 for the sql objects in general in preparation for the PreparedStatement=20 work I was going to do - which I suspect treads on your beliefs of single=20 situation Mocks and no test cases (as it uses the same implementation of=20 ResultSet for multi and single row results, and has test cases to ensure=20 the various combinations of build methods give the same results). Simon., =2D-=20 =2D------------------------------------------------------------------------- Simon Levitt, Senior Development Engineer @ WorldPay plc, WorldPay Centre, The Science Park, Milton Rd., Cambridge, CB4 0WE, ENGLAND = =20 Sim...@uk... Ph:+44(0)1223 715151 F:+44(0)1223 715157 =2D------------------------ http://www.worldpay.com/ ----------------------- |
From: Steve F. <st...@m3...> - 2002-10-27 23:09:27
|
Looking at this, one solution is not to use a Verifiable for the connection. You need a stub here, more than a mock and you're not really testing anything about how the connection behaves. You can knock up a stub implementation very quickly using anonymous classes in front of a null implementation. Alternatively, you could relax the access on the static statement and set it during the test. Alternatively, you could get more sophisticated and use AspectJ to intercept the call. From: "Simon Levitt" <sim...@uk...> > StrawMan: > > public class DataObject > { > private static Statment stmt = Global.getConnection().createStatement(); > > public DataObject(String name, int flags, boolean readOnlyRecord) > { > > public static DataObject load(String id) > { > try { > result = stmt.executeQuery("SELECT * FROM table WHERE id = " + id); > if (result.next()) { > obj = new DataObject(result.getString(1), result.getInt(3), > stmt.getConnection().isReadOnly()); > [...] > > > I figure that this will be a reasonably lightweight mechanism for > > understanding each other and for pushing the dialogue along. One case > > at a time... > > > This is probably the biggest difference, I'm not looking at a specific > single case, I'm thinking more generally. I was just trying to find a way to get there gradually, rather than in one go. > Whilst I think its important, more from a perception of MockObjects point > of view I don't much care if its taken on board any more. Particularly as > we appear to be the only two concerned about it in any form. I'm not sure that's completely true. There are quite a few lurkers. > I'd much rather be spending time presenting the rationisation I've done > for the sql objects in general in preparation for the PreparedStatement > work I was going to do - which I suspect treads on your beliefs of single > situation Mocks and no test cases (as it uses the same implementation of > ResultSet for multi and single row results, and has test cases to ensure > the various combinations of build methods give the same results). Well, I'm beginning to soften on No Test Cases, simply because I can't remember what everything does any more. That said, Nat Pryce and I have been doing some interesting work with dynamic proxies that might make some of the issues go away. I don't know if we'll ever achieve a complete implementation of the standard, so maybe we should try to go around the problem. Hmmm. I'll take another look at your previous proposal. S. |