Earlier I asked this question How to correctly unit test my DAL?, one thing left unanswered for me is if to really test my DAL is to have a Test DB, then what is the role of
Your not just testing your app, though. You are also testing your configuration and your Stored Procedures and Views. These are documented in your unit tests.
we've used transactional unit tests and that prevented Hibernate mapping problems several times. Otherwise - what's to unit test? Something trivial as List<Item> getAllItems()
? :)
I didn't find mocking very useful when testing data access code. The purpose of unit testing is to verify the database-related code works and mocking the database would hinder the test.
Mocking does indeed become useful when testing the business code. You can mock your database calls to return test data and verify the behavior of business logic in those circumstances.
Regarding the use of transactions - it's certainly possible, as long as your architecture has room for starting a transaction at the beginning of the test, and then doing all database-related calls of your unit test inside that transaction. Never tried it, though.
Putting unit tests into transactions that roll back sounds hacky. Instead of that I have code that cleans the database of any crud (i.e. anything that isn't static/reference data) before the tests run (i.e. in the constructor of my test class). When your tests fail it helps to have the data still in the database to inspect what the cause of the failure is.
By using a test database, you open up the possibility that problems could be caused at the database itself or along the communication path (network, etc) between the DAL and database. Mocking eliminates those possibilities.
I think you'll probably want to do some integration testing to check logic that is enforced by your database structure, for example constraints, triggers, autoincrement columns, etc. You should, however, for unit testing mock out whatever framework components that your DAL relies upon as you want (in your unit tests) to test only those components that you have coded. You don't really need to test methods on SqlCommand or SqlConnection (for example). You should assume that the framework components that you use work and create stubs or mocks for them that return known data (good, bad, exceptions) to your methods to make sure that your methods work properly. Without mocking you are responsible for generating the data in the database and making sure that it is correct. You also leave open dependencies on the network, the database itself, etc. that may make your tests brittle.
Also, unit testing does not remove the need for other types of testing. Integration tests and acceptance tests are still valid and need to be done. They probably don't need to be done with the same frequency as unit tests and may not need to be as extensive as your code quality improves with unit testing, but unit testing is not a magic bullet.