How to test for application exceptions Arquillian, EJB, JUnit
zeus3324 Oct 30, 2012 4:02 AMI am having problems testing application exceptions thrown within an EJB. I am using JUnit, Arquillian, JBoss. I may have a missunderstanding how EJB's should be programmed/tested. This is my first posting so if I need to clarify anything, or give more details, or provide more code, please let me know. I would appreciate any suggestions on how to test for application exceptions in an EJB.
When a runtime exception is thrown within the EJB, the transaction is destroyed, and a TransactionRequiredException is thrown. Any subsequent test (that passes when run as a single test) fails with the following exception:
javax.transaction.NotSupportedException: BaseTransaction.checkTransactionState - ARJUNA016051: thread is already associated with a transaction!
Secondly if I try to assert that the exception thrown is of type TransactionRequiredException, then i get the following exception:
java.lang.Exception: Unexpected exception, expected<javax.persistence.TransactionRequiredException> but was<java.lang.AssertionError>
The important code is below
The test class:
@RunWith(Arquillian.class)
public class PlayerDomainTestCase extends PersistenceTest {
@Deployment
public static Archive<?> createDeployment() {
return ArchiveFactory.getFullArchive();
}
@PersistenceContext
protected EntityManager em;
@Inject
protected UserTransaction utx;
@Before
public void preparePersistenceTest() throws Exception {
beginTransaction();
}
@After
public void commitTransaction() throws Exception {
utx.commit();
}
protected void beginTransaction() throws Exception {
utx.begin();
em.joinTransaction();
}
@Test(expected=TransactionRequiredException.class)
public void testRetirePlayerOnFutureDateBean() throws Exception {
// SETUP
Player player = playerDao.findAll().get(0);
// TEST - method throws IllegalArgumentException if the date is after today...
playerBean.retirePlayer(player.getId(), new DateTime().plusDays(1));
// ASSERT - TransactionRequiredException
}
@Test
public void testSavePlayerProfile() throws Exception {
// another test using an EJB, which passes if above test is commented out
// its fails only when the previous test has caused the destruction of the transaction
}
}
The EJB is below:
@Stateless
@LocalBean
@Remote(IPlayer.class)
public class PlayerBean implements IPlayer {
@Override
public ResponseDto retirePlayer(Integer playerId, DateTime retireDate) {
ResponseDto responseDto = new ResponseDto();
try {
Player player = playerDao.findById(playerId);
//method below throws IllegalArgException is date is invalid.
retirePlayerService.retire(player, retireDate);
} catch (Exception e) {
logger.error(e.getCause());
responseDto.setErrorMessage(e.getCause().getMessage());
}
return responseDto;
}
}