Testing approach - DB, Junit
i would like to ask you about writting tests which are connected with data from database. In my opinion the best way is to have a diffrent DB schema with correct data only for unit testing. In test code i can load the object on the base of ID.
The second possiblity is to putting data into database during the unit test. I dont like开发者_StackOverflow中文版 it.
What do you think. How do you do this?
Kind regards Sebastian
If you really want to write tests that interact with a database - integration tests - then you will have to put your database in a known state before each test execution.
One way to do this would be to load custom dataset before each test, for example using DbUnit. Here, each test is responsible of his own data, there is no cleanup required and you can query the database after a failed test to understand the problem.
Another way would be to use a "live" database and to run tests inside a transaction and to rollback the changes at the end of the test. Spring and Unitils have support for this. This works well too but it's not always easy to diagnose a failed test when using this approach.
Note that the second approach doesn't really exclude the first one, you can use custom dataset inside a transaction. Also note that you can use a database containing "reference data" (i.e. read-only data like countries, etc) and only load "dynamic data" to speed up things when using the first approach.
Personally, I don't really see what's wrong with the former approach (except maybe that tests are a bit slower), tools like DbUnit make it quite easy. And as I said, I find tests using DbUnit easier to diagnose. But the later approach definitely works too.
In both case you should of course use a dedicated schema1.
1 Actually, using one schema per developer is definitely a best practice.
For unit tests, you should mock or stub the functionality of the database. Since you are testing the object that calls the database and not the database itself, there is no need to use a real database. EasyMock or JMock are good mocking libraries to look into.
Three comments:
Unit tests are typically small scale, fast tests to cover a little piece of code. Tests using a DB are not really unit tests (even if you can run them in e.g. JUnit), but rather system / integration tests. Both are useful, for different purposes.
Even if your object graph is big, I don't see why you would need to test it all at once in a unit test. You test one DAO with the necessary mock objects, and assert that the relevant part of the object graph is handled correctly. Then write more tests for the next DAO etc.
IMO DAOs typically should not do very complex things (unless part of the business logic is put in there, but that's bad design - should be refactored instead of trying to cover it with contorted unit tests).
精彩评论