In the application I've been working on, we have the requirement to handle unique constraint errors gracefully.  It wasn't really hard, I just had to check for OracleException.Code == 1.  The trick was the testing.  Testing a unique constraint error was not a problem.  The issue is verifying that other exceptions are bubbled up properly.

The basic exception handling code is like this:
    1 protected bool HasUniqueConstraintError( Action databaseAction )
    2 {
    3     try
    4     {
    5         databaseAction();
    6         return false;
    7     }
    8     catch( OracleException ex )
    9     {
   10         //Return true if exception is a Unique Constraint error
   11         if( ex.Code == 1 )
   12             return true;
   13         else
   14             throw;
   15     }
   16 }
Line 14 was not getting covered in my tests.  Also, because I have the same requirement under various scenarios, I decided to move this logic to a shared library.  The shared library doesn't deal with a real connection.  (And using a real connection wouldn't be a true unit test anyway).

So, I tried to test by instantiating OracleException myself.  Alas, OracleException has no public constructors nor any way to get a new instance.  On top of that it is sealed, so I cannot create a subclass either.  Then, I thought, maybe I can use serialization.  I tried XmlSerializer, but it requires a public parameterless constructor.

Finally, I landed on SoapFormatter.  Of course, I had to have a Soap message to start from.  So, I did a little bit of work to reproduce a unique constraint exception in the debugger.  I used SoapFormatter to serialize the OracleException and wrote it to a file.  Then, I added the file to my test project (as an embedded resource).  Finally, I wrote the test to use the embedded file and deserialze to an instance of OracleException I could throw.  I did the same for another common Oracle error (ORA-12154: TNS).  I verified that the unique constraint error was handled, while the TNS error was rethrown.

Here is the test code:
    1 [Test]
    2 public void TestHasUniqueConstraintError()
    3 {
    4     SoapFormatter formatter = new SoapFormatter();
    5     Assembly asm = Assembly.GetExecutingAssembly();
    6     using( Stream stream = asm.GetManifestResourceStream( "XCIS.Data.Nunit.OracleUniqueConstraintException.txt" ) )
    7     {
    8         OracleException testException = (OracleException)formatter.Deserialize( stream );
    9         Assert.That( HasUniqueConstraintError( () => { throw testException; } ) );
   10     }
   11 }
   12 
   13 [Test, ExpectedException( ExceptionType = typeof( OracleException ) )]
   14 public void TestHasSomeOtherOracleError()
   15 {
   16     SoapFormatter formatter = new SoapFormatter();
   17     Assembly asm = Assembly.GetExecutingAssembly();
   18     using( Stream stream = asm.GetManifestResourceStream( "XCIS.Data.Nunit.OracleTNSException.txt" ) )
   19     {
   20         OracleException testException = (OracleException)formatter.Deserialize( stream );
   21         HasUniqueConstraintError( () => { throw testException; } );
   22     }
   23 }
Tags: , , ,
posted on Friday, July 25, 2008 4:45 PM
Filed Under [ .Net Oracle Database C# Quality ]

Comments

Gravatar
# re: Testing OracleException
posted by espinete
on 1/12/2011 3:50 PM
how serialize "XCIS.Data.Nunit.OracleUniqueConstraintException.txt" ?? thanks
Gravatar
# re: Testing OracleException
posted by Will
on 1/13/2011 11:49 PM
@espinete

Basically I wrote a temporary program that would result in an unique constraint exception. I caught the exception, and with an instance of the exception in hand I was able to serialize it to a file.

Clearly a little extra effort just to generate the xml file, but it helped me cover an important scenario in my testing.
Gravatar
# re: Testing OracleException
posted by kiquenet
on 11/4/2011 4:09 AM
hi, how get the "XCIS.Data.Nunit.OracleTNSException.txt" file ? thanks

Post A Comment
Title:
Name:
Email:
Comment:
Verification: