Schema Generation
Use the previous post on Schema Generation from JPA objects to make sure that a schema.sql file exists in the test resources directory. This can be used to create the database tables for H2 to then use.
Pom Dependencies
There are a few dependencies that need to be included in the pom file if they aren't already. These include JUnit, H2 and spring, as well as hibernate entity manager.
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.174</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
<scope>test</scope>
</dependency>
Spring Context for H2
This spring context (domain-test-context.xml) defines the use of H2 as the data source and initialises the database with a createSchema.sql file and the schema.sql file generated above by the hibernate4 maven plugin.<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd" >
<jdbc:embedded-database id="dataSource" type="H2" />
<jdbc:initialize-database data-source="dataSource" ignore-failures="ALL">
<jdbc:script location="createSchema.sql" />
<jdbc:script location="schema.sql" />
<!-- We could put other initialising data stuff in here -->
</jdbc:initialize-database>
<!-- This manages the entities and interactions with the database -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan" value="com.my.classes.impl" />
<property name="dataSource" ref="wiDataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" />
<property name="generateDdl" value="false" />
</bean>
</property>
<property name="jpaProperties">
<props>
<!-- General settings -->
<prop key="hibernate.archive.autodetection">class, hbm</prop>
<prop key="hibernate.current_session_context_class">jta</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="myRepository" class="com.my.classes.repo.MyRepository" />
</beans>
This context creates the H2 database and wires the MyRepository ready for testing.
The createSchema.sql file contains the line as the schema.sql generated won't generate a database schema itself only the tables / columns which are part of that schema.
create schema MY_SCHEMA;
Test Class
This is the sample test class. It uses the Spring Runner with the text context above. It is ApplicationContextAware so that we can load the repository (@Autowire could be used instead) and trust spring to use the PersistenceAnnotationBeanPostProcessor to inject the EntityManager.@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:domain-test-context.xml"})
public class WorkInstructionRepositoryTest implements ApplicationContextAware
{
/**
* This is the application context that we can load beans from.
*/
private ApplicationContext applicationContext;
/**
* JPA Entity Manager.
*/
@PersistenceContext
private EntityManager entityManager;
/**
* The class under test.
*/
private MyRepository repo;
/**
* {@inheritDoc}
*/
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException
{
this.applicationContext = applicationContext;
}
/**
* Before each test get the repository.
*/
@Before
public void before()
{
this.repo = (MyRepository) applicationContext.getBean("myRepository");
}
/**
* Test creating and loading some data.
*/
@Test
@Transactional
@Rollback(true)
public void testCreateAndReadData()
{
// Arrange
final SomeData data = new SomeData();
data.setActive(true);
data.setText("Some Data Text");
// Act
repo.createData(data);
final List<DataInterface> loadedDataObjs = repo.getAllData();
// Assert
final DataInterface loadedData = loadedDataObjs.get(0);
assertEquals(data.isActive(), loadedData.isActive());
assertEquals(data.getText(), loadedData.getText());
}
}