I want to keep Trapo environment as simple as possible. I want that people just fire a command and all tests can run immediately: no setups, no database creation, no sql to run. Just one single command and trapo should do everything for you. Because of that, I start to isolate the test environment from the production one in order to use a different database instance (or even a different database vendor). To integrate the combo, I just call HSQLDB to the party. To avoid describe exactly what is HSQLDB, here is a quote from its homepage:
HSQLDB (HyperSQL DataBase) is the leading SQL relational database engine written in Java. It has a JDBC driver and supports a rich subset of ANSI-92 SQL (BNF tree format) plus many SQL:2008 enhancements. It offers a small, fast database engine which offers both in-memory and disk-based tables and supports embedded and server modes. Additionally, it includes tools such as a minimal web server, in-memory query and management tools (can be run as applets) and a number of demonstration examples.
FIRST, CONFIGURE MAVEN...
The simplest part: just add hsqldb as a
maven dependency:
<dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>1.8.0.10</version> <scope>test</scope></dependency> I decide to scope it as test because I'm not intent to use it in production, but you can use a different scope.
SECOND, ADD TEST RESOURCES...Then, I just create two files inside src/test/resources directory. You can create files here to replace src/main/resources while running tests. But I want to reduce the amount of work to maintain both test and production enviroment, so, I'm replacing just what need to be replace: the database configuration. The two files are:
src/test/resources/hibernate.tests.propertieshibernate.connection.driver_class = org.hsqldb.jdbcDriver hibernate.connection.url = jdbc:hsqldb:mem:trapohibernate.connection.username = sa hibernate.connection.password = hibernate.c3p0.min_size=5 hibernate.c3p0.max_size=20hibernate.c3p0.timeout=1800 hibernate.c3p0.max_statements=50hibernate.dialect = org.hibernate.dialect.HSQLDialect hibernate.show_sql=truehibernate.format_sql=true hibernate.default_batch_fetch_size=5hibernate.generate_statistics=true hibernate.use_sql_comments=truehibernate.jdbc.batch_size=10 hibernate.cache.use_second_level_cache=truehibernate.cache.use_query_cache=true hibernate.cache.provider_class=net.sf.ehcache.hibernate.EhCacheProviderhibernate.cache.use_structured_entries=true hibernate.hbm2ddl.auto=create-dropNote the url property, it is pointing to an in memory database. Moreover, this files contains cache and some other optional configurations to mimic the production configurations. The other file is the Spring context to configure the SessionFactory for tests:
src/test/resources/applicationContextTest.xml<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd"> <bean id="testSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" p:annotatedClasses-ref="annotatedClasses" p:annotatedPackages="com.google.code.trapo.domain" p:hibernateProperties-ref="hibernateProperties" /> <util:list id="annotatedClasses"> <value>com.google.code.trapo.domain.Forum</value> <value>com.google.code.trapo.domain.Topic</value> </util:list> <util:properties id="hibernateProperties" location="classpath:hibernate.test.properties" /> </beans>I'm not fully confortable with that because I need to copy and past mapped classes here. But, this is a start, so I prefer to have sub-optimal solution over don't have any solution at all.
THIRD, REFACTOR YOUR TESTS...
Your tests should use SpringJUnit4Runner instead of the default one. So you have to put the following annotation in the test class:
@RunWith(SpringJUnit4ClassRunner.class)
public class MyRepositoryTests {
...
}
You also need to say to Spring where it should find the configuration files using @ContextConfiguration annotation:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:/trapo-servlet.xml",
"classpath:/applicationContextTest.xml"
})
public class MyRepositoryTests {
...
}
And, because your tests are using the database, is a good call configure them to be transactional. In order to do that, you need both @Transactional and @TransactionConfiguration annotations:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:/trapo-servlet.xml",
"classpath:/applicationContextTest.xml"
})
@Transactional
@TransactionConfiguration(transactionManager = "txManager")
public class MyRepositoryTests {
...
}
And then inject the testSessionFactory configure in applicationContextTests.xml in your tests:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:/trapo-servlet.xml",
"classpath:/applicationContextTest.xml"
})
@Transactional
@TransactionConfiguration(transactionManager = "txManager")
public class MyRepositoryTests {
@Autowired private SessionFactory testSessionFactory;
}
FINALLY, JUST RUN YOUR TESTS...And now the grand finale, just open a command prompt, go to trapo directory and type:
mvn clean testIf you want to see
cobertura report, type:
mvn clean cobertura:cobertura Hope that helps.
Comments [0]