我的测试用例中预期异常的正确组合是什么?
What is the right combination of expected exceptions in my test case?
在进行一些数据源测试时,我编写了这个小型 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();
}
}
如您所见,有一种方法可以删除条目,另一种方法可以 select。对于我的测试,我创建了一个用户,该用户在 table 上具有 select, insert, update
但没有 delete
权限。所以执行方法getAllEmps
会得到一个结果,而removeAllEmps
应该会因为权限不足而失败。
我写了这个测试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();
}
}
虽然 testGetAllEmps
测试工作顺利,但我无法让 testDeleteAllEmps
产生绿色条,因为我没有正确组合“外部”(thrown.excpect
) 异常和“内部”(thrown.expectCause
) 异常。执行测试方法时,我得到以下堆栈跟踪:
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
所以我的期望是,“外部”异常是 EJBTransaction
(因为 EJBTransactionRolledbackException
是它的子项),“内部”异常是 SQLSyntaxErrorException
。
但是即使我将 thrown.expect
更改为 EJBTransactionRolledbackException
and/or 将 thrown.expectCause
更改为 SQLGrammarException
测试仍然没有变绿。
任何人都可以帮助我确定正确的异常组合,我必须期望让我的测试用例 运行 变成绿色条吗? (甚至可能检索异常消息?)
在我看来,第一个异常是 SQLSyntaxErrorException,它引发了 SQLGrammarException,引发了 PersistenceException,引发了 EJBTransactionRolledBackException。所以你可以试试
thrown.expect(EJBException.class);
thrown.expectCause(CoreMatchers.isA(PersistenceException.class));
甚至
thrown.expect(EJBTransactionRolledBackException.class);
thrown.expectCause(CoreMatchers.isA(PersistenceException.class));
但何必呢?仅仅期待 EJBException
而不关心原因是什么还不够吗?
在进行一些数据源测试时,我编写了这个小型 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();
}
}
如您所见,有一种方法可以删除条目,另一种方法可以 select。对于我的测试,我创建了一个用户,该用户在 table 上具有 select, insert, update
但没有 delete
权限。所以执行方法getAllEmps
会得到一个结果,而removeAllEmps
应该会因为权限不足而失败。
我写了这个测试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();
}
}
虽然 testGetAllEmps
测试工作顺利,但我无法让 testDeleteAllEmps
产生绿色条,因为我没有正确组合“外部”(thrown.excpect
) 异常和“内部”(thrown.expectCause
) 异常。执行测试方法时,我得到以下堆栈跟踪:
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
所以我的期望是,“外部”异常是 EJBTransaction
(因为 EJBTransactionRolledbackException
是它的子项),“内部”异常是 SQLSyntaxErrorException
。
但是即使我将 thrown.expect
更改为 EJBTransactionRolledbackException
and/or 将 thrown.expectCause
更改为 SQLGrammarException
测试仍然没有变绿。
任何人都可以帮助我确定正确的异常组合,我必须期望让我的测试用例 运行 变成绿色条吗? (甚至可能检索异常消息?)
在我看来,第一个异常是 SQLSyntaxErrorException,它引发了 SQLGrammarException,引发了 PersistenceException,引发了 EJBTransactionRolledBackException。所以你可以试试
thrown.expect(EJBException.class);
thrown.expectCause(CoreMatchers.isA(PersistenceException.class));
甚至
thrown.expect(EJBTransactionRolledBackException.class);
thrown.expectCause(CoreMatchers.isA(PersistenceException.class));
但何必呢?仅仅期待 EJBException
而不关心原因是什么还不够吗?