If you write a utility method to get the difference between two dates, don't trust your system that it's gonna give you the same result all the time (Don't confused it with the Java slogan 'write once, run anywhere' !). The result you would get is totally dependent on the JVM, on which you are running your code. Follow the below case:
1. Create a date object from the Calendar:
Calendar cal = GregorianCalendar.getInstance();
cal.set(2008, Calendar.JANUARY, 31);
startDate = cal.getTime();
cal.set(2014, Calendar.MARCH, 31);
endDate = cal.getTime();
2. Get the difference in days:
long time1 = startDate.getTime();
long time2 = endDate.getTime();
long inDays = (time2 - time1) / 1000 * 60 * 60 * 24;
3. The result is 2250 days in -
Java(TM) 2 Runtime Environment, Standard Edition (IBM build 1.4.2_12-b03 20061117 (SR6 + 110979) ) and 2251 in Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05).
The true platform independent solution for the above issue is to add the hour:min:sec
as 23:59:59 while getting the date from the calendar.
cal.set(2014, Calendar.MARCH, 31, 23, 59, 59);
And through that you can write once and run anywhere until any new issue come up.
Note: Though I'm not yet sure but I found some posting that says this happens only if the date falls in some leap year.
Featured Post
The great debacle of healthcare.gov
This is the first time in history when the president of the United States of America, or probably for any head of state around the world,...
Wednesday, March 5, 2008
Saturday, March 1, 2008
Unit Testing of DAO classes
Data Access Objects (DAO) are important components of any software system. Ideally the DAO classes shouldn't contain any logic other than few Data access logic. In that context, the DAO classes are less error prone while changing code. But there are several reasons, as described below, those forces us to write Unit test for DAO classes.
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:
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
- 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
Friday, February 29, 2008
WebSphere Application Server
Websphere Application Server 5.1: Test Environment Setup
1. In Configure tab
Useful commands:
Check out the version of installed WAS in Solaris:
$[WAS Installed location]/bin/versionInfo.sh
1. In Configure tab
- Enable administration console
- Open Java VM Settings section add any system properties you want in your application like logger class or environment information (dev, sys or prod etc.)
- Open Node Settings
- set the ORACLE_JDBC_DRIVER_PATH to jdbc driver jar location
- Open JAAS Authentication
- Add an alias: user-auth;
- Username : <db-user>
- Password : <password>
- Open Server Settings section
- In JDBC Provider List set
- Oracle JDBC provider: Oracle Thin Driver;
- Implementation Class: OracleConnecctionPoolDataSource
- Define DataSource after choosing the just created Provider
- Class path = {ORACLE_JDBC_DRIVER_PATH}/<jdbc-driver>.jar
- Data source
- 1st Screen
- Oracle Thin Driver
- 2nd Screen
- Name: jdbc/MyDataSource
- JNDI Name: jdbc/MyDataSource
- Component Managed Auth Alias: user-auth
- Container managed auth alias: user-auth
- 3rd Screen
- Port number: <oracle-port> note: default port is 1521
- URL:jdbc:oracle:thin:@<db-host-name>:<port>:<schema-name>
Useful commands:
Check out the version of installed WAS in Solaris:
$[WAS Installed location]/bin/versionInfo.sh
Subscribe to:
Posts (Atom)