From: Stephen or C. P. <csp...@ya...> - 2001-09-07 15:43:46
|
Hi Steve, --- Steve Freeman <st...@m3...> wrote: > Interesting idea. Is this a pattern you've found yourself > writing (that's how the expectation map got written)? Yes, I have a specific situation. It may be so uncommon that you guys may decide it isn't worthwhile to put in this additional function, but I think I will need to enhance mockObjects myself (someday) even if it isn't adopted by others. Or perhaps the code design that is requires this feature is flawed? > > The thing I would like to understand is how a 'KeyedList' (or > whatever) would be better than an ExpectationList and pulling > values off a regular collection. I'm still a little doubtful.. I need to test a method that has a loop that retries a sequence of operations until a certain result is obtained. The exit condition for the loop is set by the results returned from an ExpectationList input. In order to do more than one iteration in my method under test, I need the mockObject to return back a sequence of responses, where the first and second input is identical but the 1st response does not satisfy the loop termination condition, and the 2nd response does satisfy it. I haven't been doing OOD for very long, so my approach may be faulty, but here is the code, where everything was done via mockObjects and TfD, up to where the while loop was added: The following are my first 3 unit-tests, and my 4th unit-test which I could not implement without this enhancement: public void test01SetLockWhenNoLockFound() throws Exception { myQueryStrings.addExpectedMissing( "delete from galaxy.lock_dimension where tabschema='GALAXY' "+ "and tabname='TABLE_ABC' "+ "and lck_tmstmp + 24 hours > CURRENT TIMESTAMP"); myQueryStrings.addExpectedMissing( "insert into galaxy.lock_dimension values "+ "('GALAXY','TABLE_ABC','user123',CURRENT TIMESTAMP)"); myQueryStrings.addExpected( "select lck_user_id, lck_tmstmp from "+ "galaxy.lock_dimension "+ "where tabschema='GALAXY' and tabname='TABLE_ABC' for read only", new General1().tokensToVector("user123,2001-08-23-15.04.18.351858") ); tableLock.setLock(queries, "user123", "GALAXY", "TABLE_ABC", 24, new MockLockStatus() ); myQueryStrings.verify(); } public void test02SetLockWhenLockFoundDifferentUser() throws Exception { myQueryStrings.addExpectedMissing( "delete from galaxy.lock_dimension where tabschema='GALAXY' "+ "and tabname='TABLE_ABC' "+ "and lck_tmstmp + 24 hours > CURRENT TIMESTAMP"); myQueryStrings.addExpected( "insert into galaxy.lock_dimension values "+ "('GALAXY','TABLE_ABC','user123',CURRENT TIMESTAMP)", new SQLException("tabschema/tabname duplicate key","sqlstate",-803) ); myQueryStrings.addExpected( "select lck_user_id, lck_tmstmp from "+ "galaxy.lock_dimension "+ "where tabschema='GALAXY' and tabname='TABLE_ABC' for read only", new General1().tokensToVector("user789,2001-08-23-15.04.18.351858") ); tableLock.setLock(queries, "user123", "GALAXY", "TABLE_ABC", 24, new MockLockStatus() ); myQueryStrings.verify(); } public void test03SetLockWhenLockFoundSameUser() throws Exception { myQueryStrings.addExpectedMissing( "delete from galaxy.lock_dimension where tabschema='GALAXY' "+ "and tabname='TABLE_ABC' "+ "and lck_tmstmp + 24 hours > CURRENT TIMESTAMP"); SQLException sqlException = new SQLException(null,null,-803); myQueryStrings.addExpected( "insert into galaxy.lock_dimension values "+ "('GALAXY','TABLE_ABC','user123',CURRENT TIMESTAMP)", sqlException ); myQueryStrings.addExpected( "select lck_user_id, lck_tmstmp from "+ "galaxy.lock_dimension "+ "where tabschema='GALAXY' and tabname='TABLE_ABC' for read only", new General1().tokensToVector("user123,2001-08-23-15.04.18.351858") ); myQueryStrings.addExpectedMissing( "update galaxy.lock_dimension "+ "set lck_tmstmp=CURRENT TIMESTAMP "+ "where tabschema='GALAXY' and tabname='TABLE_ABC'"); tableLock.setLock(queries, "user123", "GALAXY", "TABLE_ABC", 24, new MockLockStatus()); myQueryStrings.verify(); } /****************************** * cannot do this test without enhanced MockObject framework. Have a loop * that keeps retrying until a result comes back that says who made the * preceeding insert fail. */ public void xtest04SetLockFoundRowButNoInfo() throws Exception { myQueryStrings.addExpectedMissing( "delete from galaxy.lock_dimension where tabschema='GALAXY' "+ "and tabname='TABLE_ABC' "+ "and lck_tmstmp + 24 hours > CURRENT TIMESTAMP"); SQLException sqlException = new SQLException(null,null,-803); myQueryStrings.addExpected( "insert into galaxy.lock_dimension values "+ "('GALAXY','TABLE_ABC','user123',CURRENT TIMESTAMP)", sqlException ); myQueryStrings.addExpectedMissing( "select lck_user_id, lck_tmstmp from "+ "galaxy.lock_dimension "+ "where tabschema='GALAXY' and tabname='TABLE_ABC' for read only"); tableLock.setLock(queries, "user123", "GALAXY", "TABLE_ABC", 24, new MockLockStatus()); myQueryStrings.verify(); } --------- and here is the instance method that is under test: --------- public void setLock(Queries queries, String userid, String tabSchema, String tabName, int hoursTillStale, MultiRowObject lockStatus) throws Exception { String rmStaleLock = "delete from galaxy.lock_dimension where tabschema='"+ tabSchema+"' and tabname='"+tabName+"' "+ "and lck_tmstmp + "+hoursTillStale+ " hours > CURRENT TIMESTAMP"; String insertLock = "insert into galaxy.lock_dimension values "+ "('"+tabSchema+"','"+tabName+"','"+userid+"',CURRENT TIMESTAMP)"; String updateTime = "update galaxy.lock_dimension "+ "set lck_tmstmp=CURRENT TIMESTAMP "+ "where tabschema='"+tabSchema+"' and tabname='"+tabName+"'"; String getLockInfo = "select lck_user_id, lck_tmstmp from "+ "galaxy.lock_dimension "+ "where tabschema='"+tabSchema+"' and tabname='"+tabName+"' for read only"; queries.runExecUpdate(rmStaleLock); String lockingUser = null; while ((lockingUser == null) || lockingUser.equals("") ) { try { queries.runExecUpdate(insertLock); } catch (SQLException e) { if (e.getErrorCode() == -803) { lockingUser = getLockHolder(lockStatus, queries, getLockInfo); if ((lockingUser != null) && (lockingUser.equals(userid))) queries.runExecUpdate(updateTime); } else throw e; } lockingUser = getLockHolder(lockStatus, queries, getLockInfo); } } /*******/ public String getLockHolder(MultiRowObject lockStatus, Queries queries, String g etLockInfo) throws Exception { queries.runQuery(getLockInfo, lockStatus); return ((IntLockStatus)lockStatus).getUser(); } ----------- I apologize for the annoying line-breaks, and the un-refactored portions of the code, but this is what triggered my initial email. Thanks again for your input. __________________________________________________ Do You Yahoo!? Get email alerts & NEW webcam video instant messaging with Yahoo! Messenger http://im.yahoo.com |