Yes, it's done all the time. Improved testability is one of the main reasons to use Spring's dependency injection capabilities.
There are multiple ways to do it:
Technique 1 - Declare production DS bean and dev DS bean in two different context XMLs or ContextConfig classes
Declare them in two different contexts but give both of them the same bean ID so that DAO bean need not change.
For example, the production context XML "PROJECT/src/resources/datasource-prod.xml":
and the development context XML "PROJECT/test/resources/datasource-dev.xml":
Rest of the beans - controllers, models, DAO - are in a different context XML, say "PROJECT/src/resources/app.xml" (actually, I put beans of each layer in its own context XML to make it easy to mock out entire layers...makes unit testing very easy).
So now for production webapp, you include {app.xml, datasource-prod.xml} in the DispatcherServlet's context locations.
For unit tests, you tell Spring to load {app.xml, datasource-dev.xml} this way:
For your own adhoc test application with main method, you create ClassPathXmlApplicationContext("app.xml, datasource-dev.xml").
The concept is same even if you're using
java configuration classes instead of XML - just refactor the prod/dev datasource beans into their own config classes under PROJECT/src/ and PROJECT/test/.
Technique 2 - Use environment variables
The idea here is that values are imported into beans from environment variables or property files. This
article explains it in detail.