基于JPA的DAO测试及外键名称测试
立即解锁
发布时间: 2025-08-18 02:07:14 阅读量: 2 订阅数: 8 

### 基于 JPA 的 DAO 测试及外键名称测试
#### 1. 基于 JPA 的 DAO 测试
当确保持久化实体被正确映射后,就可以开始测试实际使用 JPA 的应用代码,如 DAO。基于 JPA 的 DAO 测试用例与实体映射测试类似,但需要覆盖更多场景,并注意一些棘手问题。
##### 1.1 简单测试用例
首先从简单的情况开始,包括 `getUserById()`、`addUser()` 和 `testRemoveUser()` 的测试用例。以下是 `UserDaoJpaImplTest` 类的初始版本:
```java
public class UserDaoJpaImplTest extends AbstractJpaDbUnitELTemplateTestCase {
UserDaoJpaImpl dao;
@Before
public void prepareDao() {
dao = new UserDaoJpaImpl();
dao.setEntityManager(em);
}
@Test
@DataSets(setUpDataSet="/user.xml")
public void testGetUserById() throws Exception {
beginTransaction();
long id = ELFunctionMapperImpl.getId(User.class);
User user = dao.getUserById(id);
commitTransaction();
assertUser(user);
}
@Test
@DataSets(assertDataSet="/user.xml")
public void testAddUser() throws Exception {
beginTransaction();
User user = newUser();
dao.addUser(user);
commitTransaction();
long id = user.getId();
assertTrue(id>0);
}
@Test
@DataSets(setUpDataSet="/user.xml",assertDataSet="/empty.xml")
public void testDeleteUser() throws Exception {
beginTransaction();
long id = ELFunctionMapperImpl.getId(User.class);
dao.deleteUser(id);
commitTransaction();
}
}
```
与之前使用纯 JDBC 实现 DAO 的测试用例相比,主要区别在于 `prepareDao()` 方法、用户 ID 的局部变量以及事务管理调用。
##### 1.2 处理用户关联电话的测试用例
由于 `User` 对象可能关联多个电话,需要添加相应的测试用例:
```java
public class UserDaoJpaImplTest extends AbstractJpaDbUnitELTemplateTestCase {
// ... 已有代码 ...
@Test
@DataSets(setUpDataSet="/user-with-telephone.xml")
public void testGetUserByIdWithTelephone() throws Exception {
beginTransaction();
long id = ELFunctionMapperImpl.getId(User.class);
User user = dao.getUserById(id);
commitTransaction();
assertUserWithTelephone(user);
}
@Test
@DataSets(assertDataSet="/user-with-telephone.xml")
public void testAddUserWithTelephone() throws Exception {
beginTransaction();
User user = newUserWithTelephone();
dao.addUser(user);
commitTransaction();
long id = user.getId();
assertTrue(id>0);
}
@Test
@DataSets(setUpDataSet="/user-with-telephone.xml",
assertDataSet="/empty.xml")
public void testDeleteUserWithTelephone() throws Exception {
beginTransaction();
long id = ELFunctionMapperImpl.getId(User.class);
dao.deleteUser(id);
commitTransaction();
}
}
```
运行这些测试时,`testDeleteUserWithTelephone()` 会失败,原因是 DAO 使用 JPA 查询删除用户时,没有考虑级联删除,只有调用 `EntityManager` 的 `remove()` 方法才会处理级联删除。
##### 1.3 负向测试用例
除了上述简单场景,还需要测试负向情况:
```java
public class UserDaoJpaImplTest extends AbstractJpaDbUnitELTemplateTestCase {
// ... 已有代码 ...
@Test(expected=IllegalArgumentException.class)
public void testAddNullUser() throws Exception {
dao.addUser(null);
}
@Test
public void testGetUserByIdOnNullDatabase() throws Exception {
getUserReturnsNullTest(0);
}
@Test
@DataSets(setUpDataSet="/user.xml")
public void testGetUserByIdUnknownId() throws Exception {
getUserReturnsNullTest(666);
}
private void getUserReturnsNullTest(int deltaId) {
beginTransaction();
long id = ELFunctionMapperImpl.getId(User.class)+deltaId;
User user = dao.getUserById(id);
commitTransaction(true);
assertNull(user);
}
}
```
这些负向测试用例展示了 `addUser()` 方法接收 `null` 引用、`getUserById()` 方法处理不存在的 ID 或从空数据库加载数据的情况。
##### 1.4 解决懒加载异常
在实际使用中,调用 `UserFacade.getUserById()` 并尝试访问用户的电话列表时,可能会抛出 `LazyInitializationException` 异常。这是因为 `User/Telephone` 关系被定义为懒加载,当在 JPA 上下文之外调用 `getTelephones()` 方法时会抛出异常。
为了模拟这个问题,修改 `testGetUserByIdWithTelephone()` 方法:
```java
@Test
@DataSets(setUpDataSet="/user-with-telephone.xml")
public void testGetUserByIdWithTelephone() throws Exception {
beginTransaction();
long id = ELFunctionMapperImpl.ge
```
0
0
复制全文
相关推荐










