- In practice any code can breaks regardless of complex or simple
- Achieve 100% code coverage by unit testing
- Testing of data access logic whatsoever is written
Our happy Engineering Manager had clicked the first link of application next day to create an account in the freshly installed system (we intentionally had kept the system fresh to show them how it will start from the very beginning when it would be deployed first) that caused the system to crash, with a NullPointerException trace printed on the browser, in front of the Board members who had come to see the already delayed project's first working presentation. Do I need to detail the situation in the demonstration room after that incident? I don't think so.
To consider unit testing for DAO classes we have to take the implementation technique based on the underlying technology used there. If hard code JDBC is used then Mock can be applied to test the behavior whether the Connection, Statement, ResultSet etc are called and closed properly. But if Hibernate is used to DAO , as O-R mapping for example, then it doesn't make sense to use Mock as the O-R mapper (e.g Hibernate) takes care of those raw objects. In that case, the testing goal would be:
- Test the O-R mapping and relationship configurations (e.g hbm.xml files)
- Query wrote in the method (e.g using Criteria or HQL)
The following class provides the Hibernate Session to the test code:
public class HibernateUtil {
private static SessionFactory factory;
public static void setSessionFactory(SessionFactory factory) {
HibernateUtil.factory = factory;
}
}
The following class creates the test schema and also helps initialize and reset the schema:
public class TestSchema {
private static final Configuration config = new Configuration();
static {
config.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect").
setProperty("hibernate.connection.driver_class", "org.hsqldb.jdbcDriver").
setProperty("hibernate.connection.url", "jdbc:hsqldb:mem:test").
setProperty("hibernate.connection.username", "sa").
setProperty("hibernate.connection.password", "").
setProperty("hibernate.connection.pool_size", "1").
setProperty("hibernate.connection.autocommit", "true").
setProperty("hibernate.cache.provider_class", "org.hibernate.cache.HashtableCacheProvider").
setProperty("hibernate.hbm2ddl.auto", "create-drop").
setProperty("hibernate.show_sql", "true").
addClass(Customer.class).
addClass(Account.class);
}
public static void reset() throws SchemaException {
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
try {
session.createQuery("Delete Customer").executeUpdate();
session.createQuery("Delete Account").executeUpdate();
} catch (HibernateException e) {
tx.rollback();
throw new SchemaException(e.getMessage());
}
finally {
tx.commit();
session.close();
}
}
public static void initialize() {
HibernateUtil.setSessionFactory(config.buildSessionFactory());
}
The actual Unite test class:
public class HibernateAccountDaoTest extends TestCase {
CustomerDao custDao;
AccountDao accountDao
public static void main(String[] args) {
junit.swingui.TestRunner.run(HibernateDaoTest.class);
}
public void setUp() {
TestSchema.initialize();
custDao = new HibernateCustomerDao();
custDao.setSession(HibernateUtil.getSession());
accountDao = new HibernateAccountDa0();
accountDao.setSession(HibernateUtil.getSession());
}
public void tearDown() {
try {
TestSchema.reset();
} catch (SchemaException e) {
e.printStackTrace();
}
}
public void testInsertAccount() {
// prepare data set
Customer customer = new Customer(1, "Name", "Address");
Account account = new Account(customer);
accountDao.insertAccount(account);
Account queriedAccount = dao.findAccountById(1);
assertNotNull(account.getBalance()));
}
}
Resources:
http://martinfowler.com/articles/mocksArentStubs.html - Truly speaking, I'd started liking mock object by reading this article
http://www.theserverside.com/tt/articles/article.tss?l=UnitTesting - I just followed this article's way
http://www.javaranch.com/journal/2003/12/UnitTestingDatabaseCode.html - The traditional approach of database code unit testing
http://www.javaranch.com/journal/2003/12/UnitTestingDatabaseCode.html - The traditional approach of database code unit testing
No comments:
Post a Comment