Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / October 2007

Tip: Looking for answers? Try searching our database.

JUnit 4 causes an error when expecting exceptions

Thread view: 
swetha - 22 Oct 2007 12:37 GMT
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
voorth - 22 Oct 2007 12:47 GMT
> I have the following test case for a method someMeth(int ID) in class
> classA():
[quoted text clipped - 42 lines]
> 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.
swetha - 22 Oct 2007 13:27 GMT
> 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)
Lew - 22 Oct 2007 14:01 GMT
voorth wrote:
>> 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)

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.

Signature

Lew

swetha - 23 Oct 2007 08:52 GMT
> The problem no doubt is in the code that you didn't post.  Post an SSCCE
> <http://www.physci.org/codes/sscce.html>
[quoted text clipped - 4 lines]
> --
> Lew

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:oracle:thin:@<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[i]);
               pStmt.addBatch();
           }

           int[] c = pStmt.executeBatch();
           for(int i = 0; i < c.length; i++)
               if(c[i] >= 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)
swetha - 23 Oct 2007 08:59 GMT
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?
voorth - 23 Oct 2007 12:53 GMT
> 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
swetha - 23 Oct 2007 14:07 GMT
> 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.
Lew - 23 Oct 2007 14:44 GMT
>> Since you hardcoded your driver class, you should probably catch the
>> ClassNotFoundException and declare the SQLException as thrown:
[quoted text clipped - 13 lines]
> 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.

Signature

Lew

Lew - 23 Oct 2007 14:49 GMT
swetha wrote:
>> 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

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?

Signature

Lew

swetha - 24 Oct 2007 08:27 GMT
> "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.
Igor Cunko - 22 Oct 2007 15:58 GMT
> I have the following test case for a method someMeth(int ID) in class
> classA():
[quoted text clipped - 25 lines]
> 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: ...... )


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.