ctimus
ctimus

Reputation: 101

Unit Testing involving DB (Insert/Update/Select)

Looking forward to know the best practice in this area and context.

Two scenarios

  1. I have a component written in Java & Spring where I am getting some data , converting it into another format that involves core business logic and insert/update a Cassandra DB.
  2. Another java component reads data from that DB, runs business logic on that and take care of some other functionalities.

Now while writing the unit test cases I can think of the below two high level approaches

  1. I can use Mockito or similar and mock the DAO object so that I don't actually call DB while doing get and save operations on DAO Object.
  2. I can actually not mock and let is connect to DB.
  3. We connect to DB only during build snapshot (for few test cases)

However -

For (1) - We are not actually testing if the data are stored/updated properly. For (2) - This should not be a good idea to do it in unit / regression as we don't want to connect to DB every time we do mvn install or build For (3) - This sounds like a better option provided this is feasible.

Question is - What is the best practice around testing the DB operations as part of the unit tests or regression test or during build. Should we always mock these calls ?

Upvotes: 1

Views: 1336

Answers (1)

Dirk Herrmann
Dirk Herrmann

Reputation: 5949

Your scenarios are quite abstract, therefore the answer is as well:

The testing scenarios you describe seem to be a mixture of unit-testing and integration-testing problems. In unit-testing you would like to test the business logic in depth (computations, but ideally no interactions with other components) with the intent to find bugs in the computational parts. Dependencies to other components (like the DB) are disturbing. In integration testing, however, you are searching for the bugs in the interaction between the different components.

Therefore, a first step would be to re-design your component such that you separate the computation-dominated parts of the code from the interaction-dominated parts. Ideally, you end up with a number of functions/methods for the computation-dominated parts that have no interactions with other components, such that you can test these functions with unit-testing but without need for mocking. In the not-so-ideal case, you still have some, but only few interactions left, so that at least the effort for mocking is reduced.

The second type of functions/methods you obtain after your re-design would be the interaction-dominated functions. Ideally, the interaction-dominated functions have no computational code, but only contain interactions with the other components. Then, for these functions, unit-testing does not make sense, since the only bugs this type of code could contain are bugs like calling functions (or performing DB operations) in a wrong order, calling the wrong function (or DB operation), passing the arguments in the wrong order, passing incompatible arguments, receiving unexpected data etc., and all these bugs can not be found with unit-testing, but with integration testing.

Upvotes: 1

Related Questions