Search code examples
javahibernateexceptionjunit4

What is the right combination of expected exceptions in my test case?


While doing some data sources testing I wrote this small EJB.

@Stateless
@Remote(IEmpService.class)
@LocalBean
public class EmpService implements IEmpService {

  @PersistenceContext
  private EntityManager em;

  public void removeAllEmps() {
    em.createQuery("DELETE FROM Emp").executeUpdate();
  }

  public List<Emp> getAllEmps() {
    return em.createQuery("FROM Emp", Emp.class).getResultList();
  }
}

As you can see there's one method to delete entries and one to select it. For my testing I created a user which has select, insert, update but no delete priviledges on the table. So executing the method getAllEmps will retrieve a result, while removeAllEmps should fail because of insufficient rights.

I wrote this test class

@RunWith(Arquillian.class)
public class DataSourceTest {

  @Deployment
  public static JavaArchive createDeployment() {
    // ...
  }

  @EJB
  EmpService testclass;

  @Rule
  public ExpectedException thrown = ExpectedException.none();

  @UsingDataSet("empBefore.xml")
  @Test
  public void testGetAllEmps() {
    List<Emp> allEmps = testclass.getAllEmps();

    Assert.assertEquals(2, allEmps.size());
  }

  @UsingDataSet("empBefore.xml")
  @Test
  public void testDeleteAllEmps() {
    thrown.expect(EJBException.class);
    thrown.expectCause(CoreMatchers.isA(SQLSyntaxErrorException.class));
    
    testclass.removeAllEmps();
  }

}     

While the testGetAllEmps test works smooths, I can't get the testDeleteAllEmps to produce a green bar as I don't get the right combination of "outer" (thrown.excpect) exception and "inner" (thrown.expectCause) exception. When executing the test method I get the following stack trace:

javax.ejb.EJBTransactionRolledbackException: org.hibernate.exception.SQLGrammarException: could not execute statement

[...]

Caused by: javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute statement

[...]

... 187 more

Caused by: org.hibernate.exception.SQLGrammarException: could not execute statement

[...]

... 217 more

Caused by: java.sql.SQLSyntaxErrorException: ORA-01031: insufficient privileges

[...]

... 226 more

So my expectation is, that the "outer" exception is an EJBTransaction (as EJBTransactionRolledbackException is a child of it) and the "inner" one is an SQLSyntaxErrorException. But even when I change the thrown.expect to EJBTransactionRolledbackException and/or the thrown.expectCause to SQLGrammarException the test still doesn't get green.

Can anybody help me to identify the correct combination of exceptions I have to expect to get my test case run a green bar? (And maybe even retrieve the exception message?)


Solution

  • It looks to me like the first exception was an SQLSyntaxErrorException, which caused an SQLGrammarException, which caused a PersistenceException, which caused an EJBTransactionRolledBackException. So you could try

    thrown.expect(EJBException.class);
    thrown.expectCause(CoreMatchers.isA(PersistenceException.class));
    

    or even

    thrown.expect(EJBTransactionRolledBackException.class);
    thrown.expectCause(CoreMatchers.isA(PersistenceException.class));
    

    but why bother? Isn't it enough just to expect an EJBException, and not be concerned about what the cause is?