Testing Exception Handling
The sign of a well design application is how gracefully it can handle errors. To be able to handle errors gracefully in all circumstances though requires lots and lots of testing. You have to test that your application is catching and handling exceptions carefully. Sometimes its hard to produce error conditions because your code is interacting with a third party library, or third party service like a database or something. You can write complex mock objects in these scenarios, but let's see how you can create these error conditions in an easier and more flexible way with JBoss AOP. The example scenario we'll give is an application that needs to be tested on whether or not it handles an Oracle database deadlock exception gracefully. What we'll do is write an advice that intercepts calls to java.sql.Statement execute methods and always throw a SQLException with the appropriate deadlock error code. public class SQLDeadlockExceptionInjector { public Object throwDeadlock(Invocation invocation) throws Throwable { throw new SQLException("Oracle Deadlock", "RETRY", ORACLE_DEADLOCK_CODE); } } What's great about the JBoss AOP approach to testing exception handling is that you can use it on a live system and change how your tests run by deploying and/or undeploying certain aspects at runtime during your automatic testing phase. Let's apply this aspect. execute*(..))"> So, the above binding will throw a deadlock exception every time an execute method of a Statement is invoked. This example is a bit limited though. Maybe not all code paths can handle deadlock exceptions, or they should not handle deadlock exceptions and just rollback and such. The pointcut expression language allows you to do more fine grain application of this particular exception aspect. Let's say that only our BankAccount class is designed to successfully recover from a Oracle deadlock exception. We can change the pointcut expression to be as follows: The difference in this expression is the within. It is saying that any call to execute methods that are within the BankAccount class. We can even get more fine grained than that. We can even specify which methods within BankAccount the exception aspect should be applied to. In the above listing the withincode keyword specificies to match the calling of any execute method that is invoked within the BankAccount.withdraw() method. AOP gives you a lot of flexibilty in testing error conditions, JBoss AOP in particular. Because JBoss AOP allows you to hotdeploy (deploy/undeploy) aspects at runtime it is very easy to integrate these types of tests into a live system instead of having to go through the pain of writing complex mock objects and running your applications outside of the application server environment.