To test whether the method findAll fulfills its role of returning all entities of a given type, the best option is to fire this query against a real database.
I explain: you are testing a very close implementation of the database. Between your code and the database, there is only the JPA framework (Eclipselink, Hibernate, whatever). Since it makes no sense to test these frameworks or the database, you have to let these components perform their work to see if your code can, from the interaction with them, deliver the expected result.
In some projects, this method of yours would even be tested because the cost of testing it is great (large dependency on other components of architecture) and the value in testing it is small (the code itself does very little, there are no important rules there to be validated). In these projects, instead of writing a test for this method, this method would be mockery, that is, it would be replaced by something else when testing another code that depends on it.
But there are other projects where the rule is that 100% of the code is covered by tests ("100% coverage"); and there is still the possibility that you want to write this type of method using TDD (where you would first write the test and then the method findAll to pass the test). In this case, how to do?
You can use a Fake instead of using a Mock
Although it is natural to call everything a "mock", perhaps a differentiation between these two types of stuntman (doubles) within your specific case:
In this another answer you have a list of other types of stuntmen.
Mock
Mock validates tested code interactions with the component that mock is replacing.
In your example, a mock would replace the Entitymanager and the other objects it delivers, and would validate whether the methods were called getCriteriaBuilder, createQuery, getResultList, etc..
Note that this does not apply because you may want to replace all this code you have today with a single line, for example:
public List<T> findAll(Class<T> entityClass) {
return entityManager.createQuery(String.format("select t from %s t",
entityClass.getSimpleName()), entityClass).getResultList();
}
If you were using the mock concept, the test of this method would fail although the method still fulfills its role. Also, you will want to test other methods like this, only more complex (using filter, for example).
Generally speaking, although we call everything "mock", rarely a real mock helps much. It is complex and the demand for it often indicates a design problem or an obtuse goal for the test being written.
Fake
Fake is a type of stunt that has a complete implementation of the component that is replacing itself.
It is used because it is more suitable for testing than the actual component (for example, faster) but cannot be used in production because of other requirements (customer prefers to use another component or this one we use as fake does not support the production load, for example).
You would use a fake here to replace the database. The databases I have successfully used for this are the H2 and the HSQLDB.
The advantage of these databases over an DBMS plus Nterprise (as Oracle and MS SQL Server) is that they can be used fully in memory and within the same testing process, eliminating the need for inter-process communication or network access and eliminating disk access, which makes testing much faster.
The testing process using a database in memory as a stuntman fake is as follows:
The project has an alternative bank access configuration, which is used only during automated tests. This setting naturally points to the database in memory.
At the start of the tests, the database is automatically created in memory from the entity settings of your project.
At the beginning of each test, i.e., in the preparation for the test, you enter in the database the entities that will be used by that particular test, and delete them at the end of the test or simply rollback the transaction.
Conslusion
It is necessary to be clear the objective of the test that is being implemented.
There are several types of stuntmen to be used in automated testing, and mock most of the time is the least indicated.
A stuntman of the type fake, on the other hand, it can be very useful for testing database access implementations or for testing services (which traverse multiple layers of architecture).
What you can test with better performance using a database fake is:
Whether queries continue to work after changing entity and attribute names or after changing table and column names in the database.
If your data access implementation (repositories or Daos) continues to work after changing a query strategy, such as the replacement I showed for your original code.
And you can also run service tests, which go through various layers of architecture, including the data bank.
But what do you want to test? When we write an automated test, we try to know for example if "given a certain input the code produces a certain output" or if "given certain conditions the system behaves in such a way". I’ve also written tests to make sure string queries don’t break after typing. So depending on the goal, you have a few different options - such as not testing :-) What you expect to know from the result your test?
– Caffé
I improved the question :) I want to test that given a certain class, I can return all records from the table.
– LeoCBS