From: Verma, N. (G. B. L529706) <Nit...@ge...> - 2002-03-07 23:26:36
|
Just leave mockobject for sec! Can you access PreparedStatement/Statement of your SQLObject object? if not ... you can't rollback a transaction properly. You will end-up having open cursors! (assert on to the closing of Statements) I can smell duplication of code here! ------------ if (obj.isMarkedDeleted()) { // jdbc code to delete obj from table } else if (obj.isMarkedChanged()) { // jdbc code to update table row for obj } else if (obj.isMarkedNew()) { // jdbck code to insert obj into table } else { // do nothing } ----------- What I fell is you are making the query string in this util class. I suggest you to make something like this: public interface SQLObject{ public void execute() throws SQLException; public void close() throws SQLException; } public class SQLObjectFactory{ public static SQLObject getSQLObject(final String operation){ // use an XML/properties file to get information on SQLObjects // Like "insert=blah.blah.InsertSQLObject" SQLObject objSQLObject = SQLConfig.getSQLObject(operation); if(objSQLObject==null){ return new NullSQLObject(); } return objSQLObject; } } public class NullSQLObject implements SQLObject{ public void execute(){ //do nothing } public void close(){ //do nothing } } public abstract AbstarctSQLObject implements SQLObject{ public final void execute throws SQLException{ //excute code using getQuery() } public final void close(){ //Code to close } protected abstract Striing getQuery(); } public class DeleteSQLObject{ protected String getQuery() // code } } public class InsertSQLObject{ protected String getQuery() // code } } public class UpdateSQLObject{ protected String getQuery() // code } } public class SQLObjectComposite{ public void addSQLObject(SQLObject objSQLObject){ //... } puclic SQLObjectIterator iterator(){ //... } public void closeAll()throws SQLException{ //... } } ----- public void update(Connection conn, SQLObjectComposite objSQLObjectComposite) { SQLObjectIterator iterator = objSQLObjectComposite.iterator(); (iterator.hasNext()) { try{ iterator.next().excute(); conn.commit(); } catch(){ conn.rollback(); } finally{ objSQLObjectComposite.closeAll(); conn.close(); } } } ------ Now .. back to mack stuff: Now u can assert for DeleteSQLObject/InsertSQLObject/UpdateSQLObject one by one and assert for commit/rollback/close in your UpdateTest! Comments? Regards, Nitin Verma -----Original Message----- From: Brian Denny [mailto:br...@dl...] Sent: Friday, March 08, 2002 3:52 AM To: Verma, Nitin (GEA, BLR, L529706) Cc: moc...@li... Subject: Re: [Mockobjects-java-users] simulating vs. reproducing behavior perhaps i should give a more concrete example. i have this utility method to stick a bunch of objects in a database. each object corresponds to a table row and "knows" how to read/write itself into a table. // pseudojava public void update(Connection conn, SQLObject[] objs) { for (each obj in objs) { if (obj.isMarkedDeleted()) { // jdbc code to delete obj from table } else if (obj.isMarkedChanged()) { // jdbc code to update table row for obj } else if (obj.isMarkedNew()) { // jdbck code to insert obj into table } else { // do nothing } } } now i want to test this method. so i write something like: public void testUpdate throws Exception { // object declarations and creation snipped obj1.markNew(); obj2.markChanged(); obj3.markDeleted(); mockStatement.setExpectedExecuteCalls(3); dbUtility.update(mockConnection, new SQLObject[] { obj1, obj2, obj3 }); mockStatement.verify(); } hmm. the above doesn't actually test that i did one insert, one delete, and one update. so i could do the three updates separately -- one for each object -- and test the query string each time: public void testUpdate throws Exception { // object declarations and creation snipped obj1.markNew(); obj2.markChanged(); obj3.markDeleted(); mockStatement.setExpectedExecuteCalls(1); mockStatement.setExpectedQueryString( "INSERT INTO objecttable values ('this is painful')"); dbUtility.update(mockConnection, new SQLObject[] { obj1 }); mockStatement.verify(); mockStatement.setExpectedExecuteCalls(1); mockStatement.setExpectedQueryString("UPDATE objecttable set ..."); dbUtility.update(mockConnection, new SQLObject[] { obj2 }); mockStatement.verify(); ... etc. ... } this is better, although now i'm not testing my ability to do all three at once. but now i decide to change my implementation of update() so that instead of calling executeUpdate() on a Statement, it gets a ResultSet, and goes through it updating and deleting and inserting rows as appropriate. oops. my tests just broke. i'm not sure what to think about this. since there is always more than one way to do an update in JDBC, it seems to follow that there is no implementation-INdependent way to test a method which is supposed to perform some set of JDBC updates depending on the state of something-or-other, if the only tools you have are tools that test which particular JDBC methods or SQL queries you performed. i don't see the point of writing implementation-dependent tests. i want to test the input-output behavior of my methods, not how they function. comments? -brian "THIS E-MAIL MESSAGE ALONG WITH ANY ATTACHMENTS IS INTENDED ONLY FOR THE ADDRESSEE and may contain confidential and privileged information. If the reader of this message is not the intended recipient, you are notified that any dissemination, distribution or copy of this communication is strictly Prohibited. If you have received this message by error, please notify us immediately, return the original mail to the sender and delete the message from your system." |