views:

340

answers:

2

Hi all,

we're currently working on testing JTA failure behaviour, on a system that receives messages using JMS, persists them, and sends results using another class.

The whole thing is tied together using Spring. Current unit tests use HSQLDB, Apache ActiveMQ and Bitronix for transaction management. Success with this has been limited, mostly because HSQLDB does not implement XA transactions.

So here is the question: how to best simulate database failures in a transaction unit test? Is there any way to make a standard JDBC driver (for Oracle, say) fail in the middle of a test?

n.b. pressing the power button is not a repeatable test :)

+1  A: 

Write a mock object for the test whose implementation throws an exception in the middle of the transaction.

Since you're using Spring, it's an easy matter to write a new, test-only implementation of the DAO interface that behaves in a repeatable, predictable manner. Inject the 'wonky DAO' only for the test.

Of course you're using the XA driver to connect to the database. Two phase commit won't work otherwise.

duffymo
Not a bad idea in terms of testing the application logic and the transaction manager, but it does not test for correct behaviour by the database driver. So I'll vote this up, but wait for further ideas.
xcut
+2  A: 

You need to decide what exactly do you want to test - for example if you want to test how Oracle would behave in XA transaction with Bitronix then mocking DAOs, as suggested by duffymo, is not going to help you. In such case you need to find a way to break connectivity in the middle of transaction and then see how Bitronix/Oracle would handle recovery - e.g. heuristic outcomes and so on.

Note that in quite a few cases there are ways to get the same functionality without actually using XA transactions. It could be simpler, faster and more testable. For example, in very common case when messages are consumed from MOM and DML executed in database there is a common pattern of how to get away without XA even so two resource managers are getting updated.

maximdim
Not bad comments, except that they are missing suggestions :) Do you have a link for the "common pattern" you refer to? Also, any suggestion on how to force a connectivity break in a repeatable manner in a unit test?
xcut
For the pattern description:http://www.oracle.com/technology/pub/articles/dev2arch/2006/01/custom-mdb-processing2.htmlAs for connectivity break it again depends on your particular setup - for example you can run start your tests in virtualized environment (VMWare) and shutdown network interface from host system, or just flip firewall rule, or connect through proxy and kill it in the process.
maximdim