Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What unit test to write for a class using generics in Java?

Taking the very specific example of the JpaDao class defined in this article:

public abstract class JpaDao<K, E> implements Dao<K, E> {
    protected Class<E> entityClass;

    @PersistenceContext
    protected EntityManager entityManager;

    public JpaDao() {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
        this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[1];
    }

    public void persist(E entity) { entityManager.persist(entity); }

    public void remove(E entity) { entityManager.remove(entity); }

    public E findById(K id) { return entityManager.find(entityClass, id); }
}

would it be best to write unit tests for all the existing entities in the application (Order, Customer, Book, etc.), or would it be acceptable to write unit tests for just one entity, as hinted by this other question? Are there any best practice regarding unit testing java classes using generics?

like image 778
Sébastien Le Callonnec Avatar asked Jan 18 '11 21:01

Sébastien Le Callonnec


People also ask

How do you write a unit test model class in Java?

@RunWith(MockitoJUnitRunner. class) public class MyClassTest{ @InjectMocks MyClass myClass; @Mock MyDAO myDAO; private MyObject myObj; private List<MyObject> objList; @Before public void setUp() throws Exception { myObj = new MyObject(); myObj.

What makes a good unit test Java?

Good unit tests should be reproducible and independent from external factors such as the environment or running order. Fast. Developers write unit tests so they can repeatedly run them and check that no bugs have been introduced.

How do you declare a generic type in a class?

A Generic Version of the Box Class To update the Box class to use generics, you create a generic type declaration by changing the code "public class Box" to "public class Box<T>". This introduces the type variable, T, that can be used anywhere inside the class.


2 Answers

You could write an abstract test class for entities which subclass this.

Eg:

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
     }
}

The contract you generic classes implement should be able to be tested just as genericlly, assuming that getEntity() sets up and relational dependencies correctly.

Therefore, by subclassing this test class for all the test cases for your generic subclasses, you get the tests for free.

like image 109
Marty Pitt Avatar answered Oct 25 '22 14:10

Marty Pitt


If using a different entity type causes different code to execute, then you need a separate test case.

I'd test as much as I could in a common set of tests that only use one entity type. If most of your code treats all entities the same, then there's no need to test it more than once. I'd set up separate test cases for any special behavior that's required where specific entity DAOs have different behavior.

like image 35
Bill the Lizard Avatar answered Oct 25 '22 12:10

Bill the Lizard