Should persistence tests depend on the data access layer implementation?

by jesm00   Last Updated October 12, 2017 15:05 PM

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 method EntityX createEntityX(EntityX entityToCreate) where EntityX 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 EntityXs 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 name Y using the method createEntityX. Then try to create another EntityX using the same name Y, again with method createEntityX, 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 name Y in the test (manually, as DatabaseAPI methods don’t accept DAO entities in it's API by design). Then try to create another EntityX using the same name Y, this time using method createEntityX, 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 about EntityXDAO. Therefore, the test should be on terms of EntityX.
  • We already have a previous test which checks that createEntityX correctly creates an EntityX 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 that createEntityX 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? Edit:

Edit, example code:

void myTest()
    EntityX entityToCreateInDatabase = instantiateBusinessEntityX()
    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))

Related Questions

Hierarchy in ER and OO Model

Updated August 16, 2017 22:05 PM