I have layered architecture in the project like Controller -> Service -> DAO. I want to write the JUnit test cases for service layer. Now as service layer will be internally calling DAO methods, why should I write different test cases for DAO layer as it is internally tested.
Some people say I need to mock DAO methods using mockito. Is it really required? Cant I directly use original code while testing service layer methods?
Provide one set of tests for your services, and a separate set of tests for the DAOs.
The DAO tests should be against a database, preferably an in-memory database. That's not just because it's easy to create it and tear it down in the test but because you will know it is yours and no one else is changing it. The DAO tests will test that your database mappings and SQL are right. You can use DBUnit to initialize the database with test data and to verify the contents of the database at the end of each test, so each test can run against a known dataset. With separate DAO tests if there are database-level problems those will be easier to distinguish, because you will see them in the DAO tests and not in the test for the services.
The services can be tested using mocks for the DAOs. Because the tests don't use a database they will execute faster (tests against a database run a lot slower, even using an in-memory database) and you can exercise a lot of different scenarios without slowing your tests down. The service layer is typically where most of your complexity will be so it will take more tests to cover it, it's much better if those tests can run quickly.
Typically you have DAOs with methods that do crud operations, and those methods get called over and over again in different ways in the services. When you limit database access to only the DAO tests you minimize the total amount of database access your tests need, and the tests run much faster.
What you talk about, having one set of tests that test all the way through (services and DAOs) against a database, is very tempting because a) it tests against real things all the way down, and b) it seems like it will be less work (also a lot of times the project doesn't have sufficient abstraction, you can't test things separately effectively, and there's no time to break things out). Lots of projects make the same decision for sensible reasons, and they all steer straight into the same tarpit trap of tests that take too long to run and which leave too many cases uncovered (because developers get discouraged about adding more test cases when their existing tests already take too long). Slow tests lead to bad code coverage and ineffective testing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With