JUnit 4 causes an error when expecting exceptions

S

swetha

I have the following test case for a method someMeth(int ID) in class
classA():

@Test(expected=java.sql.BatchUpdateException.class)
public void insertValues()
{
classA var = new classA();
var.someMeth(1);
}

This method is expected to throw a BatchUpdateException for the given
output. When the test is run, the java.sql.BatchUpdateException is
thrown and shows up in the stack trace. But the test case fails with

caused an error
Expected exception: java.sql.BatchUpdateException
java.lang.AssertionError
at
org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:
100)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at
org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:
87)
....................


Any idea why this is happening and why even though the stack trace
shows the error being thrown, it still results in an error when the
test runs?

I've also tried the following but with no difference in results:

@Test(expected=java.sql.BatchUpdateException.class)
public void someMethTester()
{
classA var = new classA();
int count = var.someMeth(1);
assertEquals("Inserting values with invalid ID case failed", 0,
count);
}


If I remove the (expected=...) part from the above and run the test
then the test passes because my assertEquals returns true but I still
have the BatchUpdateException in the stack trace.

Any inputs will be appreciated.

Thanks
 
V

voorth

I have the following test case for a method someMeth(int ID) in class
classA():

@Test(expected=java.sql.BatchUpdateException.class)
public void insertValues()
{
classA var = new classA();
var.someMeth(1);

}

This method is expected to throw a BatchUpdateException for the given
output. When the test is run, the java.sql.BatchUpdateException is
thrown and shows up in the stack trace. But the test case fails with

caused an error
Expected exception: java.sql.BatchUpdateException
java.lang.AssertionError
at
org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:
100)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at
org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:
87)
...................

Any idea why this is happening and why even though the stack trace
shows the error being thrown, it still results in an error when the
test runs?

I've also tried the following but with no difference in results:

@Test(expected=java.sql.BatchUpdateException.class)
public void someMethTester()
{
classA var = new classA();
int count = var.someMeth(1);
assertEquals("Inserting values with invalid ID case failed", 0,
count);

}

If I remove the (expected=...) part from the above and run the test
then the test passes because my assertEquals returns true but I still
have the BatchUpdateException in the stack trace.
This suggests that not only is the BatchUpdateException thrown, it is
also caught somewhere... I suggest you take a closer look at the stack
trace.
 
S

swetha

This suggests that not only is the BatchUpdateException thrown, it is
also caught somewhere... I suggest you take a closer look at the stack
trace.

The stack trace contains only calls of org.junit.internal.runners
classes except for the bottom-most entry which is
junit.framework.JUnit4TestAdapter.run(JUnit4Adapter.java:36)
 
I

Igor Cunko

swetha said:
I have the following test case for a method someMeth(int ID) in class
classA():

@Test(expected=java.sql.BatchUpdateException.class)
public void insertValues()
{
classA var = new classA();
var.someMeth(1);
}

This method is expected to throw a BatchUpdateException for the given
output. When the test is run, the java.sql.BatchUpdateException is
thrown and shows up in the stack trace. But the test case fails with

caused an error
Expected exception: java.sql.BatchUpdateException
java.lang.AssertionError
at
org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:
100)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at
org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:
87)
...................


Any idea why this is happening and why even though the stack trace
shows the error being thrown, it still results in an error when the
test runs?

Stack trace doesn't show that correct exception is thrown it shows
exception was expected and NOT thrown if you read carefully. ( Expected
exception: ...... )
 
S

swetha

The problem no doubt is in the code that you didn't post. Post an SSCCE
<http://www.physci.org/codes/sscce.html>
and let us take a look.

I'm betting voorth is correct.

Following is the method that is being tested:

public class someClass
{
private String[] valuesForID = null;

public void someClass(String[] values)
{
this.valuesForID = values;
}

public int insertValues(int ID)
{
int count = 0;

try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn =
DriverManager.getConnection("jdbc:eek:racle:thin:mad:<ip>:<port>:<sid>");

int size = this.valuesForID.length;
PreparedStatement pStmt = conn.prepareStatement("INSERT
INTO TABLEA(COLA, COLB) " +
"VALUES(?, ?)");

for(int i = 0; i < size; i++)
{
pStmt.setInt(1, ID);
pStmt.setString(this.valuesForID);
pStmt.addBatch();
}

int[] c = pStmt.executeBatch();
for(int i = 0; i < c.length; i++)
if(c >= 0)
count++;
}
catch(Exception e)
{
e.printStackTrace();
}
return count;
}
}

The table that I am inserting to is:

TABLEA
(
COLA INTEGER NOT NULL,
COLB VARCHAR2(10 BYTE) NOT NULL
)

COLA is PK and COLB is FK

Now the test case for method insertValues:

@Test(expected=java.sql.BatchUpdateException.class)
public void insertValue()
{
String[] arr = {"VALA", "VALB"};
someClass inst = new someClass(arr);
int count = inst.insertValues(1);
}

Now in this test case, the value "VALA" is not a valid FK and hence a
BatchUpdateException should be thrown and the test should not cause an
error.

When the test is run on the JUnit Test Results Statistics window I get
the following trace:

1 test caused an error.
com.tester.someClass.someClassTest FAILED
unknown caused an ERROR(0.469 s)
Expected exception: java.sql.BatchUpdateException
java.lang.AssertionError
at
org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:
100)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:
79)
at
org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:
87)
at
org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:
42)
at
org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:
88)
at
org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:
51)
at org.junit.internal.runners.JUnit4ClassRunner
$1.run(JUnit4ClassRunner.java:44)
at
org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:
27)
at
org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:
37)
at
org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:
42)
at junit.framework.JUnit4TestAdapter.run(JUnit4TestAdapter.java:
36)


On the JUnit Test Results Output window I get from the stack trace
printed from my method:

com.tester.someClass insertValues

java.sql.BatchUpdateException: ORA-02291: integrity constraint
(APPDB.TABLEA_R01) violated - parent key not found

at
oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:
498)
at
oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:
12432)
at com.tester.someClass.insertValues(someClass.java:45)
at com.tester.someClassTest.insertValue(someClassTest.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at
org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:
100)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at
org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:
87)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:
77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at
org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:
88)
at
org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:
51)
at org.junit.internal.runners.JUnit4ClassRunner
$1.run(JUnit4ClassRunner.java:44)
at
org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:
27)
at
org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:
37)
at
org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:
42)
at junit.framework.JUnit4TestAdapter.run(JUnit4TestAdapter.java:36)
at
org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:
297)
at
org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:
672)
at
org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:
567)
 
S

swetha

Is the error I'm receiving on JUnit being caused because I'm catching
the exception that is thrown in my method itself? If that is the case,
while creating test cases for methods which catch the exceptions they
create, do I not expect any exceptions and let them pass although even
in cases when an exception is thrown?
 
V

voorth

Is the error I'm receiving on JUnit being caused because I'm catching
the exception that is thrown in my method itself? If that is the case,
while creating test cases for methods which catch the exceptions they
create, do I not expect any exceptions and let them pass although even
in cases when an exception is thrown?

Basically, your code can throw either a ClassNotFoundException or a
SQLException.

Since you hardcoded your driver class, you should probably catch the
ClassNotFoundException and declare the SQLException as thrown:


public int insertValues(int ID) throws SQLException

HTH,


Henk van Voorthuijsen
 
S

swetha

Since you hardcoded your driver class, you should probably catch the
ClassNotFoundException and declare the SQLException as thrown:

public int insertValues(int ID) throws SQLException

I changed my insertValues(int ID) method to throw the SQLException and
hence in my test method I had to surround the call to the method in a
try - catch block and I replaced

@Test(expected=java.sql.BatchUpdateException.class)

with

@Test(expected=java.lang.ClassNotFoundException.class)

This however still gives me the same error with the stack traces as
before.
 
L

Lew

swetha said:
I changed my insertValues(int ID) method to throw the SQLException and
hence in my test method I had to surround the call to the method in a
try - catch block and I replaced

@Test(expected=java.sql.BatchUpdateException.class)

with

@Test(expected=java.lang.ClassNotFoundException.class)

This however still gives me the same error with the stack traces as
before.

That's because you are not throwing ClassNotFoundException, you're throwing
SQLException. The test cannot catch the exception if you don't throw it.

Review your JUnit documentation.
 
L

Lew

Just to be clear - it's the catch block that is eating your exception, so that
the test cannot catch it.
The test cannot catch the exception if you don't throw it.

Review your JUnit documentation.

If you catch it, the test will not.

"expected=Exception" means that the Exception is expected, then you don't
deliver one! How can you tell the test "expected=Exception", then wonder why
it fails when you don't give it the expected Exception?
 
S

swetha

"expected=Exception" means that the Exception is expected, then you don't
deliver one! How can you tell the test "expected=Exception", then wonder why
it fails when you don't give it the expected Exception?

I think I understand now : All Exceptions that are caught in the
actual method cannot be expected in the test method and hence given
that my method insertValues(int ID) was catching all Exceptions, I
should not have been expecting any exceptions.

Thanks for your patience. Sorry if I was slow to understand.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,235
Latest member
Top Crypto Podcasts_

Latest Threads

Top