From: Simon L. <sim...@uk...> - 2002-09-12 11:18:18
|
Hi, I've been looking into the sql Mock objects, and now in particular how to=20 verify the Expectations that have been set up. =46rom what I understand the only way to do this currently is to manually=20 code a call to verify on every MockConnection, MockStatement derived, and=20 MockResultSet derived, object from the test code. It strikes me it would be must nicer to be able to call verify on the=20 MockConnection and it ripple through the heirachy of objects. I've started looking into this, alongside other changes I'd like to=20 present in the near future, and a way of doing it would be to change=20 ExpectationMap and ReturnObjectList to allow the verifying their=20 contained objects by adding a flag to enable/disable the functionality=20 (with disable being the default). ReturnObjectList would have to keep=20 hold of returned objects in order to do this successfully. What do you think? Sensible? 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-09-13 03:57:43
|
From: "Simon Levitt" <sim...@uk...> > I've been looking into the sql Mock objects, and now in particular how to > verify the Expectations that have been set up. > > >From what I understand the only way to do this currently is to manually > code a call to verify on every MockConnection, MockStatement derived, and > MockResultSet derived, object from the test code. > > It strikes me it would be must nicer to be able to call verify on the > MockConnection and it ripple through the heirachy of objects. That's an interesting idea. Jeff has been working on "mock kits" to set up clusters of related objects, so that might be relevant. Don't forget the Verifier object that will verify all the appropriate instance variables of an object. > I've started looking into this, alongside other changes I'd like to > present in the near future, and a way of doing it would be to change > ExpectationMap and ReturnObjectList to allow the verifying their > contained objects by adding a flag to enable/disable the functionality > (with disable being the default). ReturnObjectList would have to keep > hold of returned objects in order to do this successfully. I'd like to see some concrete examples, especially for ExpectationMap which is, itself a verifiable. It's sounds like some of your tests may be going too deep. You can overspecify, as well as underspecify. Steve |
From: Simon L. <sim...@uk...> - 2002-09-13 09:01:33
|
On Friday 13 September 2002 00:07, Steve Freeman wrote: > I'd like to see some concrete examples, especially for ExpectationMap > which is, itself a verifiable. It's sounds like some of your tests may > be going too deep. You can overspecify, as well as underspecify. > Concrete example: We've got our own JDBC Connection Pool implementation which like most has=20 a finite set of actual JDBC Connections that it can allocate to threads.=20 Each piece of code wanting to use JDBC talks directly to the Pool asking=20 for a connection to a particular named databaase (through a symbolic=20 name).=20 Thus the call to the Connection Pooling classes is performed within the=20 method we want to test. e.g: public Person getPerson(String name) { // PooledConnection is a wrapper round Connection PooledConnection conn =3D ConnectionPool.getPooledConnection("persondb"); try { conn.enable(); // Actually gets JDBC Connection from pool stmt =3D conn.prepareStatement(...); results =3D stmt.exeuteQuery(); person =3D new Person(results): } catch (SQLException e) { conn.disable(); } reutrn person; } I've developed a Mocked version of the Connection Pooling system to allow=20 these methods to be tested.=20 What happens is the setup calls on MockConnectionPool populate an=20 ExpectationMap from pool name to MockPooledConnection - so you can test=20 the expectation that certain database connections will be/are being used.=20 verify() is checking expected keys vs actual keys. What I'd like to automate is the verification of the expectations set on=20 the MockPooledConnection objects contained in the ExpectationMap (ie. its=20 values).=20 I think it would also be useful to check the MockStatements contained=20 therein, and their MockResultSets as well.=20 You can obviously manually do this at the moment however verifying the=20 expectations means keeping a lot of object references locally to the test=20 method for the duration of the whole test. 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: Jeff M. <je...@mk...> - 2002-09-13 09:39:21
|
One problem you might come across is circular verifications. It's a problem we had here where you can add a statement to a connection and then the connection to the statement. When you call verify the whole thing goes into a loop. The way to get around it is probably to change verify to build up a verification set by adding it's children to it and then verifying everything in the set. You may not hit this problem but it's possible that these sort of changes would increase the chances of it happening. On Fri, 2002-09-13 at 10:01, Simon Levitt wrote: > On Friday 13 September 2002 00:07, Steve Freeman wrote: > > I'd like to see some concrete examples, especially for ExpectationMap > > which is, itself a verifiable. It's sounds like some of your tests may > > be going too deep. You can overspecify, as well as underspecify. > > > Concrete example: > > We've got our own JDBC Connection Pool implementation which like most has > a finite set of actual JDBC Connections that it can allocate to threads. > > Each piece of code wanting to use JDBC talks directly to the Pool asking > for a connection to a particular named databaase (through a symbolic > name). > > Thus the call to the Connection Pooling classes is performed within the > method we want to test. > > e.g: > > public Person getPerson(String name) { > // PooledConnection is a wrapper round Connection > PooledConnection conn = ConnectionPool.getPooledConnection("persondb"); > > try { > conn.enable(); // Actually gets JDBC Connection from pool > stmt = conn.prepareStatement(...); > > results = stmt.exeuteQuery(); > person = new Person(results): > } > catch (SQLException e) { > conn.disable(); > } > reutrn person; > } > > I've developed a Mocked version of the Connection Pooling system to allow > these methods to be tested. > > What happens is the setup calls on MockConnectionPool populate an > ExpectationMap from pool name to MockPooledConnection - so you can test > the expectation that certain database connections will be/are being used. > verify() is checking expected keys vs actual keys. > > What I'd like to automate is the verification of the expectations set on > the MockPooledConnection objects contained in the ExpectationMap (ie. its > values). > > I think it would also be useful to check the MockStatements contained > therein, and their MockResultSets as well. > > You can obviously manually do this at the moment however verifying the > expectations means keeping a lot of object references locally to the test > method for the duration of the whole test. > > Simon., > -- > -------------------------------------------------------------------------- > Simon Levitt, Senior Development Engineer @ WorldPay plc, > WorldPay Centre, The Science Park, Milton Rd., Cambridge, CB4 0WE, ENGLAND > Sim...@uk... Ph:+44(0)1223 715151 F:+44(0)1223 715157 > ------------------------- http://www.worldpay.com/ ----------------------- > > > > ------------------------------------------------------- > 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 -- jeff martin information technologist mkodo limited mobile: 44 (0) 78 5547 8331 phone: 44 (0) 20 2226 4545 email: je...@mk... www.mkodo.com |
From: Steve F. <st...@m3...> - 2002-10-03 12:01:16
|
Incidentally, you might want to look at using AspectJ to test this kind of stuff, then you could override the implementation of getPooledConnection() and return whatever you want. See http://www.xprogramming.com/xpmag/virtualMockObjects.htm for an example. S. ----- Original Message ----- From: "Simon Levitt" <sim...@uk...> To: "Steve Freeman" <st...@m3...> Cc: <moc...@li...> Sent: Friday, September 13, 2002 10:01 AM Subject: Re: [MO-java-dev] verify()ing object hierachies. > On Friday 13 September 2002 00:07, Steve Freeman wrote: > > I'd like to see some concrete examples, especially for ExpectationMap > > which is, itself a verifiable. It's sounds like some of your tests may > > be going too deep. You can overspecify, as well as underspecify. > > > Concrete example: > > We've got our own JDBC Connection Pool implementation which like most has > a finite set of actual JDBC Connections that it can allocate to threads. > > Each piece of code wanting to use JDBC talks directly to the Pool asking > for a connection to a particular named databaase (through a symbolic > name). > > Thus the call to the Connection Pooling classes is performed within the > method we want to test. > > e.g: > > public Person getPerson(String name) { > // PooledConnection is a wrapper round Connection > PooledConnection conn = ConnectionPool.getPooledConnection("persondb"); > > try { > conn.enable(); // Actually gets JDBC Connection from pool > stmt = conn.prepareStatement(...); > > results = stmt.exeuteQuery(); > person = new Person(results): > } > catch (SQLException e) { > conn.disable(); > } > reutrn person; > } > > I've developed a Mocked version of the Connection Pooling system to allow > these methods to be tested. > > What happens is the setup calls on MockConnectionPool populate an > ExpectationMap from pool name to MockPooledConnection - so you can test > the expectation that certain database connections will be/are being used. > verify() is checking expected keys vs actual keys. > > What I'd like to automate is the verification of the expectations set on > the MockPooledConnection objects contained in the ExpectationMap (ie. its > values). > > I think it would also be useful to check the MockStatements contained > therein, and their MockResultSets as well. > > You can obviously manually do this at the moment however verifying the > expectations means keeping a lot of object references locally to the test > method for the duration of the whole test. > > Simon., > -- > -------------------------------------------------------------------------- > Simon Levitt, Senior Development Engineer @ WorldPay plc, > WorldPay Centre, The Science Park, Milton Rd., Cambridge, CB4 0WE, ENGLAND > Sim...@uk... Ph:+44(0)1223 715151 F:+44(0)1223 715157 > ------------------------- http://www.worldpay.com/ ----------------------- > > > > ------------------------------------------------------- > 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 > |
From: Simon L. <sim...@uk...> - 2002-09-13 10:28:19
|
On Friday 13 September 2002 10:36, Jeff Martin wrote: > One problem you might come across is circular verifications. It's a > problem we had here where you can add a statement to a connection and > then the connection to the statement. When you call verify the whole > thing goes into a loop. > About 30 seconds before this arrived I was sitting here trying to work out= =20 why that exact problem had occurred! - Thanks a lot - Thats saved me=20 ages! Is that the reason a MockStatement wasn't automatically associated with=20 the Connection its added to? One of the changes I've made locally is to=20 do this (for ResultSets and their Statement as well). > The way to get around it is probably to change verify to build up a > verification set by adding it's children to it and then verifying > everything in the set. > Wouldn't it be easier for the Verifier to keep a list of objects its in=20 the process of verifying and not allow the same one twice (silently=20 doesn't bother)?=20 Making Verifier.verifyObject synchronized would stop problems with=20 multiple threads verifying at the same time (why you'd do that I don't=20 know though). > You may not hit this problem but it's possible that these sort of > changes would increase the chances of it happening. > Thanks again for the quick spot!. Cheers, 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: Jeff M. <je...@mk...> - 2002-09-13 10:58:35
|
On Fri, 2002-09-13 at 11:28, Simon Levitt wrote: > On Friday 13 September 2002 10:36, Jeff Martin wrote: > > One problem you might come across is circular verifications. It's a > > problem we had here where you can add a statement to a connection and > > then the connection to the statement. When you call verify the whole > > thing goes into a loop. > > > About 30 seconds before this arrived I was sitting here trying to work out > why that exact problem had occurred! - Thanks a lot - Thats saved me > ages! > ;-) Did I mention I'm a clairvoyant in my spare time. > Is that the reason a MockStatement wasn't automatically associated with > the Connection its added to? One of the changes I've made locally is to > do this (for ResultSets and their Statement as well). It's a general policy to not have mocks manage the relationships with other mocks. The idea is to keep the mocks as simple as possible. This is the reason I've started work on the test helper classes which setup the tree of mocks for you. Though I've not produced any for the JDBC classes as it's more complex than the servlet api. > > > The way to get around it is probably to change verify to build up a > > verification set by adding it's children to it and then verifying > > everything in the set. > > > Wouldn't it be easier for the Verifier to keep a list of objects its in > the process of verifying and not allow the same one twice (silently > doesn't bother)? Don't think this helps if the dependency is more than one level deep. > > Making Verifier.verifyObject synchronized would stop problems with > multiple threads verifying at the same time (why you'd do that I don't > know though). Tempted to say forget thread safety (That's not to say it's okay to have static variables.). > > > You may not hit this problem but it's possible that these sort of > > changes would increase the chances of it happening. > > > Thanks again for the quick spot!. > > Cheers, > > Simon., > -- > -------------------------------------------------------------------------- > Simon Levitt, Senior Development Engineer @ WorldPay plc, > WorldPay Centre, The Science Park, Milton Rd., Cambridge, CB4 0WE, ENGLAND > Sim...@uk... Ph:+44(0)1223 715151 F:+44(0)1223 715157 > ------------------------- http://www.worldpay.com/ ----------------------- > > > > ------------------------------------------------------- > 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 -- jeff martin information technologist mkodo limited mobile: 44 (0) 78 5547 8331 phone: 44 (0) 20 2226 4545 email: je...@mk... www.mkodo.com |
From: Simon L. <sim...@uk...> - 2002-09-13 14:23:15
Attachments:
veriDiff.txt
|
On Friday 13 September 2002 11:55, Jeff Martin wrote: > It's a general policy to not have mocks manage the relationships with > other mocks. The idea is to keep the mocks as simple as possible. > > This is the reason I've started work on the test helper classes which > setup the tree of mocks for you. Though I've not produced any for the > JDBC classes as it's more complex than the servlet api. > I can see this being helpful when there is a collection of objects that=20 need to be associated to sets of each other that have no real defined=20 (single) parent object, but the association of ResultSet to Statement to=20 Connection is a very simple child to single parent relationship. Or am I=20 missing something? My changes do the association at usage time (I didn't say that before=20 TBF), in that when a Statement or ResultSet gets returned, it is=20 automatically associated with the Object that you called to get it (I=20 can't see a situation, for JDBC at least, where you would want this any=20 different - or infact has any advantage). The set<Parent> interface is still required, as you may have methods to=20 test that take a ResultSet, or Statement, for which the parent object=20 needs manually setting. > Don't think this helps if the dependency is more than one level deep. [...] > Tempted to say forget thread safety (That's not to say it's okay to > have static variables.). > I've got a change (cvs diff -u attached) to Verifier that now at least=20 works for me. It has a static Vector (simplest why I could think of) of in verify()=20 objects, and ignores any object already being verified. It also doesn't=20 require any interface change. This solves my problem, and unless specific object implementations of=20 verify cause a loop (which was a potential problem anyway), I can't see=20 how this is any worse. 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: Jeff M. <je...@mk...> - 2002-09-16 10:59:40
|
Looks reasonable, but could we have a test case for it. It's the sort of thing that could get broken. On Fri, 2002-09-13 at 15:23, Simon Levitt wrote: > On Friday 13 September 2002 11:55, Jeff Martin wrote: > > It's a general policy to not have mocks manage the relationships with > > other mocks. The idea is to keep the mocks as simple as possible. > > > > This is the reason I've started work on the test helper classes which > > setup the tree of mocks for you. Though I've not produced any for the > > JDBC classes as it's more complex than the servlet api. > > > I can see this being helpful when there is a collection of objects that > need to be associated to sets of each other that have no real defined > (single) parent object, but the association of ResultSet to Statement to > Connection is a very simple child to single parent relationship. Or am I > missing something? > > My changes do the association at usage time (I didn't say that before > TBF), in that when a Statement or ResultSet gets returned, it is > automatically associated with the Object that you called to get it (I > can't see a situation, for JDBC at least, where you would want this any > different - or infact has any advantage). > > The set<Parent> interface is still required, as you may have methods to > test that take a ResultSet, or Statement, for which the parent object > needs manually setting. > > > Don't think this helps if the dependency is more than one level deep. > [...] > > Tempted to say forget thread safety (That's not to say it's okay to > > have static variables.). > > > I've got a change (cvs diff -u attached) to Verifier that now at least > works for me. > It has a static Vector (simplest why I could think of) of in verify() > objects, and ignores any object already being verified. It also doesn't > require any interface change. > > This solves my problem, and unless specific object implementations of > verify cause a loop (which was a potential problem anyway), I can't see > how this is any worse. > > Simon., > -- > -------------------------------------------------------------------------- > Simon Levitt, Senior Development Engineer @ WorldPay plc, > WorldPay Centre, The Science Park, Milton Rd., Cambridge, CB4 0WE, ENGLAND > Sim...@uk... Ph:+44(0)1223 715151 F:+44(0)1223 715157 > ------------------------- http://www.worldpay.com/ ----------------------- > ---- > > Index: Verifier.java > =================================================================== > RCS file: /cvsroot/mockobjects/mockobjects-java/src/core/com/mockobjects/util/Verifier.java,v > retrieving revision 1.3 > diff -u -r1.3 Verifier.java > --- Verifier.java 28 Mar 2002 18:16:54 -0000 1.3 > +++ Verifier.java 13 Sep 2002 13:46:34 -0000 > @@ -3,6 +3,7 @@ > import com.mockobjects.Verifiable; > > import java.lang.reflect.Field; > +import java.util.Vector; > > /** > * Helper class to verify all {@link com.mockobjects.Expectation Expectation}s > @@ -35,6 +36,8 @@ > * @version $Id: Verifier.java,v 1.3 2002/03/28 18:16:54 custommonkey Exp $ > */ > public class Verifier { > + > + private static Vector myProcessingObjects = new Vector(); > /** > * Public, no-op constructor. > * You should not need to instantiate this object, since all methods > @@ -70,7 +73,7 @@ > * Recursively verifies all fields of the passed object. > * @param anObject The object to be verified. > */ > - static public void verifyObject(Object anObject) { > + static synchronized public void verifyObject(Object anObject) { > verifyObjectFromClass(anObject, anObject.getClass()); > } > > @@ -85,15 +88,24 @@ > * @param aClass The apparent class of <code>anObject</code> > */ > static private void verifyObjectFromClass(Object anObject, Class aClass) { > + if (myProcessingObjects.contains(anObject)) { > + return; > + } > if (isRootClass(aClass)) { > return; > } > > verifyObjectFromClass(anObject, aClass.getSuperclass()); > - > - Field[] fields = aClass.getDeclaredFields(); > - for (int i = 0; i < fields.length; ++i) { > - verifyField(fields[i], anObject); > + try { > + myProcessingObjects.addElement(anObject); > + > + Field[] fields = aClass.getDeclaredFields(); > + for (int i = 0; i < fields.length; ++i) { > + verifyField(fields[i], anObject); > + } > + } > + finally { > + myProcessingObjects.removeElement(anObject); > } > } > -- jeff martin information technologist mkodo limited mobile: 44 (0) 78 5547 8331 phone: 44 (0) 20 2226 4545 email: je...@mk... www.mkodo.com |
From: Simon L. <sim...@uk...> - 2002-09-16 14:31:15
Attachments:
veriDiff.txt
|
On Monday 16 September 2002 11:56, Jeff Martin wrote: > Looks reasonable, but could we have a test case for it. It's the sort > of thing that could get broken. > Ok.. I've implemented tests for an object referencing itself, and the=20 classic two objects referencing each other. In writing the test cases it became easier to (ie. may test examples would= =20 only work if this was done) initially check whether we've processed the=20 item before calling verify(). I left the original processing check in as it could catch a manually=20 called verify() for objects previously automatically checked. (A coding style, and supporting methods for verify() could be suggested=20 that would reduce the possibility of loops occuring in test specific=20 verify methods). New diff -u attached 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: Simon L. <sim...@uk...> - 2002-09-16 14:36:46
|
On Monday 16 September 2002 15:31, Simon Levitt wrote: > New diff -u attached > Sorry, Shoud of attempted to compile after copy and paste... diff below to be=20 applied after diff: =2D-- Verifier-damn.java Mon Sep 16 15:34:38 2002 +++ Verifier.java Mon Sep 16 15:32:55 2002 @@ -90,7 +90,7 @@ * @param aClass The apparent class of <code>anObject</code> */ static private void verifyObjectFromClass(Object anObject, Class=20 aClass) { =2D if (myProcessingObjects.contains(fieldObject)) { + if (myProcessingObjects.contains(anObject)) { return; } if (isRootClass(aClass)) { =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/ ----------------------- |