Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I bother unit testing my repository layer

Tags:

unit-testing

Just putting this one out for debate really.

I get unit testing. Sometimes feels time consuming but I'm all for the benefits.

I've an application set up that contains a repository layer and a service layer, using IoC, and I've been unit testing the methods.

Now I know the benefits of isolating my methods for unit testing so there is little or no dependency on other methods.

The question I've got is this. If I only ever access my repository methods through my service layer methods would only testing the service layers not be good enough? I'm testing against a test database.

Could it not be considered an extension of the idea that you only need to test your public methods? Maybe I'm just trying to skip some testing ;)

like image 231
mat-mcloughlin Avatar asked Dec 15 '10 17:12

mat-mcloughlin


People also ask

Should unit tests hit the database?

"...the database should not be hit when the unit tests run..." - unless you're unit testing persistence objects, of course.

Where should the unit test reside in the repository?

The developers should write unit tests alongside the source code and execute them in pipelines. Separating the repositories keeps more clean environment. Repositories contain only things it's concerned about.

Should I unit test crud?

If all your application does is CRUD, then there is no point in unit testing it. Now, if there is any kind of business logic manipulating the values as they come out of the db or validating them before them going in, yes, it is a good idea to build unit tests. Testing the CRUD part does not belong in unit testing IMO.


1 Answers

Yes, you should test your repository layer. Although the majority of these tests fall into a different classification of tests. I usually refer to them as integration tests to distinguish them from my unit tests. The difference being that there is an external dependency on a resource (your database) and that these tests will likely take much longer to run.

The primary reason for testing your repositories separately is that you'll be testing different things. The repository is responsible for handling translation and interaction with whatever persistence store you're using. The service layer, on the other hand, is responsible for coordinating your various respositories and other dependencies into functionality that represents business logic, which likely involves more than just a relay to a repository method and in some instances may involve multiple calls to multiple repositories.

First, to clarify the service layer testing - when testing the service layer, the repositories should be mocked so that they are isolated from what you're testing in the service layer. As you pointed out in your comment, this gives you a more granular level of testing and isolates the code under test. Your unit tests will also run much faster now because there are no database connections slowing them down.

Now, here are a few advantages of adding integration tests to your repositories...

  1. It allows you to test out those pieces of code as you're writing them, a la TDD.
  2. It ensures that whatever persistence language you're using (SQL, HQL, serialized objects, etc.) is formulated correctly for the operation you're attempting to perform.
  3. If you're using an object-relational mapper, it ensures that your mappings are defined correctly.
  4. In the future, you may find that you need to support another type of persistence. Depending on how your repository tests are structured, you may be able to reuse a large number of the tests to verify that the new database schema works correctly. For repository methods that implement database specific logic, obviously you'll have to create separate tests.
  5. When coupled with Continuous Integration it's nice to have the repository tests separated. Integration tests, by nature take longer to run than unit tests. As such, they're usually run at less frequent intervals so that the immediate feedback available from running unit tests is not delayed.

Those are all advantages that I've seen in various projects that I've worked on. There may be more.

All that having been said, I will admit that I'm not as thorough with the repository integration tests as I am with unit tests. When it comes to testing an update on a particular object, for example, I'm usually content testing that one database column was successfully updated rather than creating a separate test for each individual column or a larger test that verifies every column in one test. For me, it depends on the complexity of the operation that the respository method is performing and whether there's any special condition that needs to be isolated.

like image 101
carmbrester Avatar answered Oct 19 '22 17:10

carmbrester