Currently we are developing the data access layer of a CRUD application. We have the following structure:
- We have business entities which are used outside the data access layer to perform the business logic.
- We have DAO entities which are used in the data access layer to store the data in our database. These entities are only data objects that map one to one to our database tables. They live inside our data access layer and cannot be used outside of this layer.
- We have a class, let’s call it
DatabaseAPI
, responsible which offers the crud API for our business entities. For example it has the methodEntityX createEntityX(EntityX entityToCreate)
whereEntityX
is a business entity. This method is responsible for transforming the entity received into the corresponding DAO entities (some business entities map to more than one DAO entity), save the DAO entities and transform and return the resulting DAO entities back into the business entity.
We are currently having a discussion on how to properly test the DatabaseAPI
methods. Particularly we have the following restriction: EntityX
has a name field, there cannot exist two EntityX
s with the same name. This restriction is enforced by the DatabaseAPI
(currently as a unique constraint in our database, but we could use a query inside a transaction to check it manually), therefore we are adding a test to check that such restriction is correctly enforced, however we have the following disagreement:
- I think the test should create an
EntityX
with a given nameY
using the methodcreateEntityX
. Then try to create anotherEntityX
using the same nameY
, again with methodcreateEntityX
, and check that it fails with the correct exception. - My coworker thinks we should create an
EntityXDAO
, the correspondig DAO entity (or entities if there is more than one), with nameY
in the test (manually, asDatabaseAPI
methods don’t accept DAO entities in it's API by design). Then try to create anotherEntityX
using the same nameY
, this time using methodcreateEntityX
, and check that it fails with the correct exception.
So basically, we disagree on the test setup. My reasoning is:
- The DAO entities are an implementation detail and should be avoided on the tests.
- The restriction we are testing is about
EntityX
, not aboutEntityXDAO
. Therefore, the test should be on terms ofEntityX
. - We already have a previous test which checks that
createEntityX
correctly creates anEntityX
when there are no conflicts.
My coworker’s reasoning is:
- In my proposed test, we would be using the method
createEntityX
do the test setup and then using it again for the actual test, checking thatcreateEntityX
throws the correct exception if an entity with the given name already exists.
The question is, should our test setup use the createEntityX
method in its setup? Should we manually create the required DAO entities? Are there any alternative we are missing?
Example code:
void myTest()
{
EntityX entityToCreateInDatabase = instantiateBusinessEntityX()
databaseAPI.createEntityX(entityToCreateInDatabase)
Assertions.assertThrows(MyDuplicityError.class, () -> databaseAPI.createEntityX(entityToCreateInDatabase))
}
void coworkersTest()
{
EntityX entityToCreateInDatabase = instantiateBusinessEntityX()
databaseAPI.getEntityDAO<EntityXDAO, Long>().create(new EntityXDAO(entityToCreateInDatabase))
Assertions.assertThrows(MyDuplicityError.class, () -> databaseAPI.createEntityX(entityToCreateInDatabase))
}
createEntityX
to testcreateEntityX
" doesn't make sense to me.