在Java中使用泛型为类编写什么单元测试?
以本节中定义的在Java中使用泛型为类编写什么单元测试?,java,unit-testing,generics,jpa,dao,Java,Unit Testing,Generics,Jpa,Dao,以本节中定义的JpaDao类为例: 公共抽象类JpaDao实现Dao{ 保护类实体类; @持久上下文 受保护的实体管理器实体管理器; 公共JpaDao(){ ParameteredType genericSuperclass=(ParameteredType)getClass().getGenericSuperclass(); this.entityClass=(类)genericSuperclass.getActualTypeArguments()[1]; } public void pers
JpaDao
类为例:
公共抽象类JpaDao实现Dao{
保护类实体类;
@持久上下文
受保护的实体管理器实体管理器;
公共JpaDao(){
ParameteredType genericSuperclass=(ParameteredType)getClass().getGenericSuperclass();
this.entityClass=(类)genericSuperclass.getActualTypeArguments()[1];
}
public void persist(E实体){entityManager.persist(实体);}
public void remove(实体){entityManager.remove(实体);}
公共E findById(K id){return entityManager.find(entityClass,id);}
}
最好为应用程序中的所有现有实体编写单元测试(
Order
、Customer
、Book等),还是可以只为一个实体编写单元测试,如本文所示?关于使用泛型对java类进行单元测试,有什么最佳实践吗?如果使用不同的实体类型会导致执行不同的代码,那么您需要一个单独的测试用例
我会在一组只使用一种实体类型的通用测试中尽可能多地进行测试。如果您的大多数代码对所有实体都一视同仁,那么无需对其进行多次测试。我为特定实体DAO具有不同行为时所需的任何特殊行为设置了单独的测试用例。来自JUnit常见问题解答:
4) 我应该在什么条件下测试get()和set()方法?
单元测试旨在减轻人们对某些东西可能会崩溃的恐惧。如果您认为get()或set()方法可以合理地中断,或者实际上导致了缺陷,那么请务必编写一个测试。
简而言之,测试直到你有信心为止。根据您的经验和信心水平,您选择的测试是主观的。切记要务实,最大限度地增加测试投资 它还指出: “测试直到恐惧变成无聊。”
我不认为你的问题是针对泛型的,因为即使你没有使用泛型,问题仍然是一样的。在这种情况下,我会选择测试一个对象(出于测试目的,可以是真实的,也可以是罐装的)。当您发现问题时,然后编写测试来解决这些特定的缺陷 您可以为这个类的子类实体编写一个抽象测试类 例如:
公共抽象类JpaDaoTest{
抽象受保护的E getEntity();
抽象保护JpaDao getDAO();
@试验
public void testPersistCreatesEntity()
{
JpaDao dao=getDAO();
persist(getEntity());
//断言
}
}
假设getEntity()
正确地设置了关系依赖项,则泛型类实现的契约应该能够像常规一样进行测试
因此,通过为泛型子类的所有测试用例对该测试类进行子类化,您可以免费获得测试。如果需要测试类的类型语义行为,我会检查类型不变量。换句话说,试着为所有类型的组合建立一些正确的断言,不仅是那些你期望使用的类型,还有宇宙中的任何类型,包括那些尚未发明的类型。例如:
private <K, E> void testTypes(K k, E e) {
JpaDao<K, E> dao = new JpaDaoImpl<K, E>();
dao.persist(e);
assertEquals(dao.getById(e.getId()).getClass(), e.getClass());
}
@Test
public void testIntegerAndOrder() {
this.<Integer, Order>testTypes(10, new Order());
}
看看断言的语义在这里有什么不同:这个测试使用变量ID的具体值来测试存储对象持有其ID的断言,而不是像之前的测试那样使用类型变量。像BalusC一样,我建议测试具体的实现。原因是它符合“你不需要它”的原则。添加足够的测试,以便您尝试实现的用例能够通过。然后,当您添加更多用例时,添加更多的单元测试。测试具体类避免以后重写它的问题 做一般测试很漂亮,但不安全 您可以在开发过程中复制粘贴大部分单元测试,然后可以自定义测试
public abstract class JpaDaoTest<K,E> {
abstract protected E getEntity();
abstract protected JpaDao getDAO();
@Test
public void testPersistCreatesEntity()
{
JpaDao dao = getDAO();
dao.persist(getEntity());
// assert
}
}
private <K, E> void testTypes(K k, E e) {
JpaDao<K, E> dao = new JpaDaoImpl<K, E>();
dao.persist(e);
assertEquals(dao.getById(e.getId()).getClass(), e.getClass());
}
@Test
public void testIntegerAndOrder() {
this.<Integer, Order>testTypes(10, new Order());
}
@Test
public void testDao() throws Exception {
JpaDao<Integer, Order> dao = getDao();
Order order = ...;
order.setId(10);
dao.persist(order);
assertEquals(order, dao.findById(10));
}