|
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
|