During my learning of testing in Java, I faced a thing which I didn't really get. So, basically, I have unit tests for DAO where I test CRUD operations with the help of in-memory database HSQL.
Well, the next step is to test the Service layer. On the web, they say to use mocks to mock DAO and then test Service.
I see only one way to use mocks: if there are some methods in Service and those methods don't exist in DAO. Then, we don't need to test CRUD operation(DAO itself), therefore we mock DAO and test only Service.
I'd like to know what are the benefits to use mocks instead of an in-memory database . Moreover, I guess, it is less readable when use Mocks.
If it makes any sense - I use Spring.
This is a broad and potentially contentious topic…so be prepared for a wide variety of answers and divergent view points…
The advantage of in-memory databases:
Disadvantages of in memory databases:
The advantage of mocks:
Disadvantages of mocks:
To answer the first question you asked about what happens when you have the same method in both -- easy answer. They aren't the same method. They're doing two different things. One's communicating with the database, the other is applying business logic. If you do have a pass through, you should still probably throw a test on it in the service layer too, to make sure it's calling the right thing on your DAO.
No matter which way you go, don't forget to also integration test your code!
Speaking from experience (of having written thousands of automated tests):
Avoid mocking as much as possible, as it's not conducive to good, proper tests. Usually, tests that use mocking are written from the wrong point of view, where the developer thinks only of executing the implementation code, rather than checking meaningful business-oriented behavior. Good tests are written from requirements , not merely to exercise code.
Integration tests can be fast enough (what really matters is that developers don't get discouraged from running them often), and they can be made to run in rollback-only DB transactions, therefore ensuring test isolation.
Use your development database (usually a shared remote db using the same db engine as in production, where the application can be manually tested as well) rather than an in-memory db. This way, you avoid the expensive in-memory db schema creation on every test run (assuming the dev db is always up and running, with all tables, which is normally the case), and any potential issues caused by using two different db technologies.
The above describes the approach I use in Java web applications (using Java EE or Spring, doesn't matter) having hundreds of tables in a relational db (accessed with JPA/Hibernate). There is only one test suite of out-of-container integration tests, where each test runs in a single db transaction which is always rolled back. Some tests do a bit of mocking, in particular for calls to remote web services, but that's it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.