Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中使用泛型为类编写什么单元测试?_Java_Unit Testing_Generics_Jpa_Dao - Fatal编程技术网

在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));
}