Spring provides the module or utility library for integration tests. The following are the steps to write JUnit tests using the Spring transaction management API and SpringJUnit4ClassRunner
:
integration.xml
in the integration
source package. Modify the XML file and define the dataSource
, transactionManager
, and JdbcTemplate
Spring beans. The following is the XML body:<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver"/> <property name="url" value="jdbc:derby:derbyDB;create=true"/> <property name="username" value="dbo"/> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> </beans>
To find out more about Spring beans, visit http://docs.spring.io/spring/docs/1.2.9/reference/beans.html.
A dataSource
bean is defined with driverClassName
, url
, and username
. The dataSource
reference is passed to the jdbcTemplate
and transactionManager
beans.
SpringJUnit4ClassRunner
handles the integration tests. Add a PhoneBookDerbySpringDaoIntegrationTest
JUnit test and add the following lines to it:@ContextConfiguration({ "classpath:integration.xml" }) @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true) @Transactional @RunWith(SpringJUnit4ClassRunner.class) public class PhoneBookDerbySpringDaoIntegrationTest { @Autowired JdbcTemplate jdbcTemplate; PhoneBookDerbySpringDao springDao; @Before public void init() { springDao = new PhoneBookDerbySpringDao(jdbcTemplate); } @Test public void integration() throws Exception { PhoneEntry entry = newEntry("12345", "John", "Smith"); //create assertTrue(springDao.create(entry)); //retrieve List<PhoneEntry> phoneEntries = springDao.searchByFirstName("John"); //verify create assertFalse(phoneEntries.isEmpty()); //modify last name entry.setLastName("Kallis"); //update assertTrue(springDao.update(entry)); //retrieve phoneEntries = springDao.searchByFirstName("John"); //verify update assertFalse(phoneEntries.isEmpty()); assertEquals("Kallis", phoneEntries.get(0).getLastName()); //delete springDao.delete(entry.getPhoneNumber()); //retrieve phoneEntries = springDao.searchByFirstName("John"); //verify delete assertTrue(phoneEntries.isEmpty()); } }
The @ContextConfiguration({ "classpath:integration.xml" })
annotation instructs the JUnit runner to load Spring beans from a classpath location. It will load three beans from the integration.xml
file.
The class level @Transactional
annotation makes all methods transactional.
The @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
annotation defines the transaction manager, and the defaultRollback
attribute tells the transaction manager to roll back all transactions after the end of a given test.
The following things happen when the JUnit test is run:
integration.xml
file.jdbcTemplate
bean is automatically wired to the test class member jdbcTemplate
.init
method creates a new instance of the dao class and passes the jdbcTemplate
bean to the dao.PhoneEntry
.PhoneBook
table.When the JUnit test runs, the following Spring console log is shown:
INFO: Began transaction (1): transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@569c60]; rollback [true] Apr 11, 2014 10:02:25 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener endTransaction INFO: Rolled back transaction after test execution for test context [[TestContext@134eb84 testClass = PhoneBookDerbySpringDaoIntegrationTest, testInstance = com.packt.database.dao.PhoneBookDerbySpringDaoIntegrationTest@1522de2, testMethod = integration@PhoneBookDerbySpringDaoIntegrationTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@425743 testClass = PhoneBookDerbySpringDaoIntegrationTest, locations = '{classpath:integration.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader']]]
The log shows that a transaction has begun, and finally the transaction is rolled back. However, the transaction was not rolled back due to any exception, rather it got rolled back due to the transactional setting [defaultRollback = true]
. The log shows that testException
is equal to null
, which implies that no exception was thrown.