#14 Incorrect AssertionFailedError message

open
Steve Freeman
None
5
2002-12-16
2002-12-11
Greg Perkins
No

There is a problem within the CommonMockStatement
class. I have created a MockPreparedStatement that
extends the CommonMockPreparedStatement (included
below).

Within this class I have implemented counters for the
addBatch and clearBatch calls. The counters work
correctly, but if the count is not correct, I receive a very
misleading assertion failure (also shown below).

Notice that the message indicates the incorrect number
of "executeCalls" was received. I thought that there
must be some user error in my MockPreparedStatement
until I saw the same behavior and exact same message
when the incorrect number of ExpectedSetParameters
was hit. I haven't modified that code.

To reproduce, create a MockPreparedStatement and call
the addExpectedSetParameters method twice, but run it
on code that actually tries to set the statements
parameters 3 or more times. You will get the following
error. This error is very misleading and could result in
hours of unnecessary debugging time for the
unsuspecting user.

*********** Assertion Failure ***********
junit.framework.AssertionFailedError:
CommonMockStatement.executeCalls did not receive
the expected Count.
Expected: 1
Received: 0
at junit.framework.Assert.fail(Assert.java:51)
at
com.mockobjects.AbstractExpectation.assertEquals
(AbstractExpectation.java:39)
at
com.mockobjects.AbstractExpectation.assertEquals
(AbstractExpectation.java:17)
at
com.mockobjects.ExpectationCounter.verify
(ExpectationCounter.java:37)
at com.mockobjects.util.Verifier.verifyField
(Verifier.java:77)
at
com.mockobjects.util.Verifier.verifyFieldsForClass
(Verifier.java:63)
at
com.mockobjects.util.Verifier.verifyFieldsForClass
(Verifier.java:57)
at
com.mockobjects.util.Verifier.verifyFieldsForClass
(Verifier.java:57)
at com.mockobjects.util.Verifier.verifyObject
(Verifier.java:49)
at com.mockobjects.MockObject.verify
(MockObject.java:44)
at
com.tivoli.tec.eds.AddRemarksWorkRequestUnitTest.tea
rDown(AddRemarksWorkRequestUnitTest.java:802)
at junit.framework.TestCase.runBare
(TestCase.java:143)
at junit.framework.TestResult$1.protect
(TestResult.java:106)
at junit.framework.TestResult.runProtected
(TestResult.java:124)
at junit.framework.TestResult.run
(TestResult.java:109)
at junit.framework.TestCase.run
(TestCase.java:131)
at junit.framework.TestSuite.runTest
(TestSuite.java:173)
at junit.framework.TestSuite.run
(TestSuite.java:168)
at junit.framework.TestSuite.runTest
(TestSuite.java:173)
at junit.framework.TestSuite.run
(TestSuite.java:168)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.ru
nTests(RemoteTestRunner.java:329)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.ru
n(RemoteTestRunner.java:218)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.m
ain(RemoteTestRunner.java:151)

*********** MockPreparedStatement***********
import java.sql.SQLException;

import com.mockobjects.ExpectationCounter;
import
com.mockobjects.sql.CommonMockPreparedStatement;

public class MockPreparedStatement extends
CommonMockPreparedStatement
{
/**
* Return values for executeBatch
*/
private int[] myBatchCount = new int[] { 0 };

/**
* addBatch <code>ExpectationCounter</code>
*/
private ExpectationCounter myAddBatchCalls =
new ExpectationCounter
("MockPreparedStatement.addBatch");

/**
* clearBatch <code>ExpectationCounter</code>
*/
private ExpectationCounter myClearBatchCalls =
new ExpectationCounter
("MockPreparedStatement.clearBatch");

/**
* Increments the number of times that addBatch() is
called.
*/
public void addBatch() throws SQLException
{
myAddBatchCalls.inc();
} // end addBatch method

/**
* Increments the number of times that clearBatch() is
called.
*/
public void clearBatch() throws SQLException
{
myClearBatchCalls.inc();
} // end clearBatch method

/**
* Returns executeBatch(String) with an empty String.
*/
public int[] executeBatch() throws SQLException
{
return executeBatch("");
} // end executeBatch method

/**
* Simulates the executeBatch call.
*
* Sets the actual SQL string received by the method
for later testing.
* Calls innerExecute() to increment the executeCount
and throw an
* exception if necessary. Returns the appropriate
established batch count.
*/
public int[] executeBatch(String sql) throws
SQLException
{
myQueryString.setActual(sql);
innerExecute();
return myBatchCount;
} // end executeBatch method

/**
* Sets the <code>ExpectationCounter</code> for
calls to clearBatch().
*/
public void setExpectedClearBatchCalls(int callCount)
{
myClearBatchCalls.setExpected(callCount);
} // end setExpectedClearBatchCalls method

/**
* Sets the <code>ExpectationCounter</code> for
calls to addBatch().
*/
public void setExpectedAddBatchCalls(int callCount)
{
myAddBatchCalls.setExpected(callCount);
} // end setExpectedAddBatchCalls method

/**
* Sets the return values for calls to executeBatch.
*/
public void setupBatchCount(int[] batchCount)
{
myBatchCount = batchCount;
} // end setupBatchCount method
} // end MockPreparedStatement class

Discussion

  • Steve Freeman
    Steve Freeman
    2002-12-16

    Logged In: YES
    user_id=123464

    Very odd. The only thing I can think of is that the
    expectation is getting reset somewhere. Could you
    upload an example of one of your tests?

     
  • Steve Freeman
    Steve Freeman
    2002-12-16

    • assigned_to: nobody --> smgf
     
  • Greg Perkins
    Greg Perkins
    2002-12-16

    Logged In: YES
    user_id=652617

    I am unable to send the actual code that is being tested or
    the test cases used to create them for confidentiality
    reasons. However, I have created a simple class and
    accompanying test case that I will send shortly (with the
    next comment).

    I have discovered (I think) why the executeCalls count is
    wrong in the situation where the incorrect number of
    parameters is set. I think that the test case fails
    immediately, then the number of calls to execute count is
    never actually set. In addition, the verify method probably
    reports on this property before reporting on others, so it
    comes up as the primary failure, even though something else
    actually caused the error.

    Just a thought and if that is the case, then I can live with
    that one. However, it may be a good idea to move the count
    checks to be the very last thing that happens when verify is
    called. That way, more descriptive, detailed error messages
    will be reported first.

    Again, this is just a thought. I'll send the example code
    shortly.

     
  • Greg Perkins
    Greg Perkins
    2002-12-16

    ZIP containing simple class, test class, and modified MockPreparedStatement

     
    Attachments
  • Greg Perkins
    Greg Perkins
    2002-12-16

    Logged In: YES
    user_id=652617

    OK...I'm including the simple class and test class here along with my modified MockPreparedStatement that has
    the add/clear batch methods implemented with counters. I now believe that the errors have everything to do with
    the order in which the mock objects are "verified". I have found a way to get the correct error message...if the test
    case sets the expected number of calls to add/clearBatch to something greater than what it actually receives and
    nothing else is wrong, then the error message is correct. If, however, you change only the number of calls to
    add/clearBatch that are expected to something less than what actually gets called, then "other" errors get caught
    first.

    This can be very misleading. I have included the files with this comment. Please try different combinations of
    values and statements being commented out to see all the different types of messages you will get. The test
    class currently has 5 test cases (only 1 of which will pass). I tried to demonstrate several different scenarios and
    error messages.

    Suggestion: Another approach to this problem would be to comment the order in which these errors are reported.
    However, I think that the problem is a little deeper than that. If you go into the add/clearBatch test methods and
    uncomment ALL lines and run it once with different values for the number of expected calls, you should still get the
    same error as long as nothing else has been changed. This, however, won't happen.

    Thanks!