The @RunWith annotation is part of JUnit 4 and is set to use SpringJUnit4ClassRunner to run the unit test.
The other annotations, except for @Test, are Spring annotations. @ContextConfiguration initializes
the Spring context and by default looks for a Spring XML file in the same package as the unit test with the file name the same as
the class with '-context.xml' as a suffix (ex: PersonDaoTransactionUnitTest-context.xml.). @TransactionConfiguration
and @Transactional configure transactions for the tests.
The method with @Test is the main test method which saves a person in a transaction. The method with @BeforeTransaction
is run before the transaction starts and the method with @AfterTransaction is run after the transaction ends.
They both use SimpleJdbcTemplate to directly check the database and avoid any caching Hibernate might be performing.
Example 1. PersonDaoTransactionUnitTest
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@TransactionConfiguration
@Transactional
public class PersonDaoTransactionUnitTest extends AbstractTransactionalJUnit4SpringContextTests {
final Logger logger = LoggerFactory.getLogger(PersonDaoTransactionUnitTest.class);
protected static int SIZE = 2;
protected static Integer ID = new Integer(1);
protected static String FIRST_NAME = "Joe";
protected static String LAST_NAME = "Smith";
protected static String CHANGED_LAST_NAME = "Jackson";
@Autowired
protected PersonDao personDao = null;
/**
* Tests that the size and first record match what is expected
* before the transaction.
*/
@BeforeTransaction
public void beforeTransaction() {
testPerson(true, LAST_NAME);
}
/**
* Tests person table and changes the first records last name.
*/
@Test
public void testHibernateTemplate() throws SQLException {
assertNotNull("Person DAO is null.", personDao);
Collection<Person> lPersons = personDao.findPersons();
assertNotNull("Person list is null.", lPersons);
assertEquals("Number of persons should be " + SIZE + ".", SIZE, lPersons.size());
for (Person person : lPersons) {
assertNotNull("Person is null.", person);
if (ID.equals(person.getId())) {
assertEquals("Person first name should be " + FIRST_NAME + ".", FIRST_NAME, person.getFirstName());
assertEquals("Person last name should be " + LAST_NAME + ".", LAST_NAME, person.getLastName());
person.setLastName(CHANGED_LAST_NAME);
personDao.save(person);
}
}
}
/**
* Tests that the size and first record match what is expected
* after the transaction.
*/
@AfterTransaction
public void afterTransaction() {
testPerson(false, LAST_NAME);
}
/**
* Tests person table.
*/
protected void testPerson(boolean beforeTransaction, String matchLastName) {
List<Map<String, Object>> lPersonMaps = simpleJdbcTemplate.queryForList("SELECT * FROM PERSON");
assertNotNull("Person list is null.", lPersonMaps);
assertEquals("Number of persons should be " + SIZE + ".", SIZE, lPersonMaps.size());
Map<String, Object> hPerson = lPersonMaps.get(0);
logger.debug((beforeTransaction ? "Before" : "After") + " transaction. " + hPerson.toString());
Integer id = (Integer)hPerson.get("ID");
String firstName = (String)hPerson.get("FIRST_NAME");
String lastName = (String)hPerson.get("LAST_NAME");
if (ID.equals(id)) {
assertEquals("Person first name should be " + FIRST_NAME + ".", FIRST_NAME, firstName);
assertEquals("Person last name should be " + matchLastName + ".", matchLastName, lastName);
}
}
}