I\'m working on trying to implement a JUnit test to check the functionality of a DAO. (The DAO will create/read a basic object/table relationship).
The trouble
Spring 3 offers a new jdbc
namespace that includes support for embedded databases, including HSQLDB. So that takes care of that part.
I'm wondering what the "in-house solution" could be. You can use annotations (either JPA or Hibernate annotations) to ORM your domain objects, so why do you need an "in-house solution"? E.g.:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource"
p:packagesToScan="myapp.model" />
As far as implementing a test goes, use Spring's TestContext Framework. A test can look like this (again I'm assuming Spring 3 below, though it should work in Spring 2.5 simply by changing @Inject to @Autowired):
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
"/beans-datasource-it.xml",
"/beans-dao.xml",
"/beans-service.xml",
"/beans-web.xml" })
@Transactional
public class ContactControllerIT {
@Inject private ContactController controller;
... setUp() and tearDown() ...
@Test
public void testGetContact() {
String viewName = controller.getContact(request, 1L, model);
... assertions ...
}
}
You'd put the embedded database inside beans-datasource-it.xml
, for example. ('it' here stands for integration test, and the files are on the classpath.) The controller in this example lives in beans-web.xml
, and will be autowired into the ContactController
field.
That's just an outline of what to do but hopefully it's enough to get you started.
I have recently implemented a similar solution in some of my code using Hibernate, Spring and HSQLDB.
Its is worth noting that AbstractTransactionalJUnit4SpringContextTests
has now be deprecated - but it is still pretty straight forward to test - I cover most the details here: http://automateddeveloper.blogspot.com/2011/05/hibernate-spring-testing-dao-layer-with.html
My application context looks a bit different
<beans:bean class="org.apache.commons.dbcp.BasicDataSource" id="HSQL_DS">
<beans:property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<beans:property name="url" value="jdbc:hsqldb:mem:Test"/>
<beans:property name="username" value="sa"/>
<beans:property name="password" value=""/>
</beans:bean>
<jdbc:embedded-database id="HSQL_DS">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:data.sql"/>
</jdbc:embedded-database>
and my test class looks like this:
public class Tester {
private EmbeddedDatabase db;
@Before
public void setUp(){
db = new EmbeddedDatabaseBuilder().addDefaultScripts().build();
}
@Test
public void TestMe(){
System.out.println("Testing");
}
@After
public void tearDown(){
db.shutdown();
}
}
See here. It assumes maven2 as build tool, but you can easily use anything.
The bottom line with hibernate is the SessionFactory
- your in-house solution will most likely be creating one of these somehow. Find out how, and then add a bean to create one in your test app context in the same way (or if possible using your in-house code that is used at runtime.). You may need to create your own FactoryBean to do the instantiation. (Use AbstractFactoryBean as your base class.)
Once this is in place, most of the examples using LocalSessionFactoryBean can be migrated to your situation - instead of using LocalsessionFactoryBean, use your custom factory bean.
(If you've not done so already, look at the Testing section in the spring reference - it makes testing with Spring, and injecting tests with beans from the context a breeze.)