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 |