Are Tests of Service Methods That Rely on Database Access Unit Tests?

It is often argued whether tests that need a database should be called “unit tests”. Most often the answer is “No, these are database integration tests”. My opinion is – “Yes”.

The whole problem is routed in the fact that service methods depend on data access. If an application is designed properly the data access is abstracted in the DAO layer, so the code is testable.

So why is it proper to call these tests “unit tests”. Because service methods (units) are tested. These methods have a dependency on the Data Access layer, which in turn depends on a database. Now, a purely unit-testing approach would be to mock the dependency – the DAO in this case. This mock should be fairly complex in order to behave as expected. So why creating a complex mock, if you can instead use an in-memory database (HSQLDB/Derby/JavaDB), which can be realized as a mock of the runtime setup.

Here’s why this is not a database integration testing – you are not testing whether your application integrates with a real database. You test the business operations that rely on database operations. But the way these operations are performed is practically mocked (though not in the standard sense)

In regard to build speed concerns – in-memory databases are (logically) very fast. This alone can reduce the amount of time for running the tests to levels low enough.

8 thoughts on “Are Tests of Service Methods That Rely on Database Access Unit Tests?”

  1. Hi Bozho!

    Thanks for answering my question at stackoverflow and for this blog post.

    You wrote
    >>in-memory databases are very (logically) fast. This alone can reduce the amount of time for running the tests to levels low enough.

    Does it mean that you should always mock objects on those tests which will require lots of maintenance in future or will likely to change in the future – so this tests will be runned more times than some other tests.

    In some way – it is like an investment. You invest more time now to save it on lots of runs in the future.

    But for “simple” tests which you won’t run much more times than others you can write “in cheap way” by not using Mock objects and with real DB queries.

    Am I right on this point? And what do you think about this idea?
    How can I product more value(save more development time) in less time? Is it a correct destination to go to meet this purpose?

  2. By in-memory database I mean full-featured products like (in Java) HSQLDB or Derby. They execute real queries, and have support in ORM tools, and support ANSI SQL, transactions, etc.

    Running some tests more than others is a wrong strategy – run all tests on every build.

  3. >> run all tests on every build.
    yes, you’re right. Maybe I get used to this anti-pattern because of utilizing real DB in tests which makes test running quite slow.

    I like your idea about using in-memory database such as HSQLDB or sqlite. But what do you think about this idea:

    1. Separated Business domain and DAL(Data access level) allows you make tests even faster, because then you don’t need even db like HSQLDB. But it takes more time to implement.

    2. Domain logic without clear separation of DAL layer saves some development time, at least at the beginning. But makes a build a little slower(we use HSQLDB at this point).

    Build time in these 2 cases are comparable values(at least in comparison with “real db”).

    Does it mean that I should Choose second way and utilize HSQLDB in tests? Can it give more benefits on the same resouces(time)? Bozho, what would you recommend here?

  4. You should separate Data Access, that’s for sure.
    And then use a db like HSQLDB to save time mocking the Data Access Layer.

Leave a Reply

Your email address will not be published.