|
From: Keith Q. <ke...@qm...> - 2004-01-14 12:38:08
|
Greetings from the North,
I have a question with regards to multiple executes within a method under
test.=20
LET ME EXPLAIN, I have a Person instance that I wish to make persistent and
I therefore invoke Person.persist() passing in the database connection. The
persit() method determines from its current state if this is an insert or a=
n
update and accordingly persists the associated data into the relational
database. When this is a simple update there is no problem. See extract fro=
m
test case: -
//extracts from testCase
public class TestPerson extends TestCaseMo{
public TestPerson(String name) {
super(name);
}
private MockConnection2 mockConnection =3D new MockConnection2();
private MockPreparedStatement mockPreparedStatement =3D new
MockPreparedStatement();
private MockStatement mockStatement =3D new MockStatement();
private MockLogger logger =3D new MockLogger(); //mocks the logger
interface setting all levels active
public void testUpdatePerson() throws SQLException {
setExpectationsForUpdatePerson();
person.setLogger(logger);
person.setFirstName(FIRSTNAME2);
person.persist(mockConnection);
verifyJDBC();
}
private void setExpectationsForUpdatePerson() {
=20
mockConnection.setupAddPreparedStatement(PersonImpl.UPDATE_PERSON_SQL,mockP=
r
eparedStatement);
mockConnection.setupStatement(mockStatement);
mockPreparedStatement.addExpectedSetParameters(UPDATE_PERSON_ROW);
mockPreparedStatement.addUpdateCount(1);
mockPreparedStatement.setExpectedCloseCalls(1);
mockConnection.setExpectedRollbackCalls(0);
mockConnection.setExpectedCommitCalls(0); //commit is by calling
method not persist(Connection con)!
}
private void verifyJDBC() {
mockConnection.verify();
mockStatement.verify();
mockPreparedStatement.verify();
}
}
However, when I test the more complicated case =B3insert=B2 this approach fails=
.
Insert creates multiple objects using a unique sequence ID from the
associated person table as a reference. See additional extract: -
public void testInsertNewRegistration(){
//note that insert new person also invokes getNextval as this is
required for the FK in
//associated tables. Therefore need to test for Select NextVal also
setExpectationsForPersonNextVal();
setExpectationsForInsertRegistration();
person.setLogger(logger);
person.setId(0);
person.persist(mockConnection);
verifyJDBC();
}
private void setExpectationsForInsertRegistration(){
=20
mockConnection.setupAddPreparedStatement(PersonImpl.INSERT_NEW_REGISTRATION=
_
SQL,mockPreparedStatement);
mockConnection.setupStatement(mockStatement);
=20
mockPreparedStatement.addExpectedSetParameters(INSERT_NEW_REGISTRATION_ROW)=
;
mockPreparedStatement.addUpdateCount(1);
mockPreparedStatement.setExpectedCloseCalls(1);
mockConnection.setExpectedRollbackCalls(0);
mockConnection.setExpectedCommitCalls(0); //commit is by calling
method not persist(Connection con)!
}
private void setExpectationsForPersonNextVal(){
=20
mockConnection.setupAddPreparedStatement(SELECT_NEXTVAL_SQL,mockPreparedSta=
t
ement);
mockConnection.setupStatement(mockStatement);
mockPreparedStatement.addExpectedSetParameter(1,"seq_person");
mockPreparedStatement.addUpdateCount(1);
}
}
//run
junit.framework.AssertionFailedError:
CommonMockPreparedStatement.setParameters did not receive an expected item
Unexpected:1=3Dseq_Person
at=20
com.mockobjects.ExpectationSet.checkImmediateValues(ExpectationSet.java:17)
at=20
com.mockobjects.AbstractExpectationCollection.addActual(AbstractExpectation=
C
ollection.java:17)
at=20
com.mockobjects.sql.CommonMockPreparedStatement.setObject(CommonMockPrepare=
d
Statement.java:237)
at=20
com.mockobjects.sql.CommonMockPreparedStatement.setString(CommonMockPrepare=
d
Statement.java:172)
at com.nowfollowme.core.Utils.getNextSeqValue(Utils.java:603)
at com.nowfollowme.account.PersonImpl.persist(PersonImpl.java:867)
at=20
com.nowfollowme.account.TestPerson.testInsertNewRegistration(TestPerson.jav=
a
:818)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at=20
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:3=
9
)
at=20
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImp=
l
.java:25)
at com.intellij.rt.execution.junit2.JUnitStarter.main(Unknown Source)
This seems to be due to prepairedStatement being overwritten with the secon=
d
set of expectations. What I would ideally like is the facility to push
multiple sets of expectations and have them popped/verified in the order
that they were specified. Is this possible or have I missed the point
somewhere along the line.
The reason that persist() has this problem is that when a record is inserte=
d
into the database persist() first gets the next available sequence value fo=
r
the person table and persist() uses this value (personId) as a foreign key
into other associated records thereby calling multiple executes on the
connection.
Any ideas?
Keith
|