/**
* @Created Aug 26, 2010 2:56:32 PM
* @author r39
*/
package com.philip.journal.core.dao;
import static org.junit.Assert.assertNotNull;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.jdbc.SimpleJdbcTestUtils;
import org.springframework.test.util.ReflectionTestUtils;
import com.philip.journal.core.JournalTestCommon;
import com.philip.journal.core.bean.User;
/**
* Base class for all DAO unit test class. This will directly read Objects from the database, thus avoiding
* the dependency to other application DAOs.
*/
@ContextConfiguration(locations = { "/test/config/daoContext.xml" })
public abstract class BaseJournalTestDAO extends AbstractJUnit4SpringContextTests { // NOPMD by r39 on 4/1/11 4:12 PM
/** Extensible logger. */
private transient Log logger = LogFactory.getLog(getClass()); // NOPMD by r39 on 3/30/11 6:02 PM
/** Refactored common functionality. */
private final JournalTestCommon common = new JournalTestCommon();
/** SQL to read Entry. */
static final String SQL_READ_ENTRY = "SELECT * FROM jrnl.ENTRY where ENTRY_ID = ?";
/** SQL to read Branch. */
static final String SQL_READ_BRANCH = "SELECT * FROM jrnl.BRANCH where BRANCH_ID = ?";
/** SQL to read user from DB. */
private static final String SQL_USER = "SELECT * FROM JRNL.USER WHERE USERNAME=?";
/** RTFC. */
private static final String TBL_BRANCH = "jrnl.BRANCH";
/** RTFC. */
private static final String TBL_ENTRY = "jrnl.ENTRY";
/** RTFC. */
private static final String TBL_CONFIG = "jrnl.CONFIG_ITEM";
/** Spring context jdbc template for db functionality. */
private transient SimpleJdbcTemplate jdbcTemplate;
// Dependent on Test Scripts.
/** Used on test First Branch ID. */
protected static final long ID_1ST_TST_BRANCH = 40001L;
/** Used on test First Entry ID. Used same ID with Branch. */
protected static final long ID_1ST_TST_ENTRY = ID_1ST_TST_BRANCH;
/** Used on test of leaf less Branch. */
protected static final long ID_NOLEAF_BRANCH = 40015L;
/** Used on test of leafed non-root Branch. */
protected static final long ID_LEAFED_BRANCH = 40007L;
/** Used on test of ordered Entry. */
protected static final long ID_FIRST_ASC = 40010L;
/** Used on test of ordered Entry. */
protected static final long ID_FIRST_DESC = 40009L;
/** Used on test of leafed non-root Branch. Count of leaves. */
protected static final long CNT_BRANCH_LEAVES = 3;
/** Non existent in test, Branch ID nor Entry ID. */
protected static final long ID_NON_EXISTENT = 49094L;
/** Test Entry count. Available in EntryDAOImplTest.sql */
protected static final long COUNT_TEST_ENTRY = 10;
/** RTFC. */
protected static final int ROOT_BRANCH_COUNT = 3;
/**
* Default setup. Will initialize DB state based on SQL scripts derived from the test class name.
*
* @throws Exception JUnit3 signature for compatibility.
*/
@Before
public void setUp() throws Exception {
setJdbcTemplate(new SimpleJdbcTemplate((DataSource) applicationContext.getBean("dataSource")));
SimpleJdbcTestUtils.executeSqlScript(getJdbcTemplate(), new ClassPathResource(
"/test/config/CreateSchema.sql"), false);
SimpleJdbcTestUtils.executeSqlScript(getJdbcTemplate(), new ClassPathResource(
"/test/config/CreateData.sql"), false);
final String testSqlPath = getTestSqlPath();
if (testSqlPath != null) {
try {
LogFactory.getLog(BaseJournalTestDAO.class).info("Running script: " + testSqlPath);
SimpleJdbcTestUtils.executeSqlScript(getJdbcTemplate(), new ClassPathResource(testSqlPath),
false);
} catch (final DataAccessResourceFailureException darf) {
LogFactory.getLog(BaseJournalTestDAO.class).warn(
"SQL script for " + getClass().getSimpleName() + " was not found.");
}
}
}
/**
*
* @throws Exception JUnit3 signature for compatibility.
*/
@After
public void tearDown() throws Exception {
SimpleJdbcTestUtils.executeSqlScript(getJdbcTemplate(), new ClassPathResource(
"/test/config/DeleteSchema.sql"), false);
}
protected String getTestSqlPath() {
return "/" + getClass().getName().replaceAll("\\.", "/") + ".sql";
}
/**
* This requires the sub class to supply the DAO implementation under test. This will allow this class to
* test common testable parts of the object under test.
*
* @return Target DAO Impl to test.
*/
protected abstract Object getTargetDAOImpl();
/**
* Generic verification that entity is defined for the DAO.
*/
@Test
public void testGetTargetClass() {
assertNotNull("DAO under test must return not null on getTargetClass call.",
ReflectionTestUtils.invokeGetterMethod(getTargetDAOImpl(), "targetClass"));
}
/**
* Directly read a record in the database in form of a Map.
*
* @param entryId Entry ID to read.
* @return Map representation of the Entity.
*/
protected Map<String, Object> readEntry(final long entryId) {
Map<String, Object> retval = null;
try {
retval = getJdbcTemplate().queryForMap(SQL_READ_ENTRY, new Object[] { Long.valueOf(entryId) });
} catch (final DataAccessException nodatafound) {
Logger.getLogger(BaseJournalTestDAO.class).error(nodatafound.getMessage(), nodatafound);
}
return retval;
}
/**
* Returns a column_name to value map of the entity.
*
* @param branchId Branch ID.
* @return the Map representation of the Branch,
*/
protected Map<String, Object> readBranch(final long branchId) {
Map<String, Object> retval = null;
try {
retval = getJdbcTemplate().queryForMap(SQL_READ_BRANCH, new Object[] { Long.valueOf(branchId) });
} catch (final DataAccessException nodatafound) {
Logger.getLogger(BaseJournalTestDAO.class).warn("Test data read yields no result.", nodatafound);
}
return retval;
}
/**
* Returns all branch in the test DB environment.
*
* @return all branch read from the test DB.
*/
protected List<Map<String, Object>> readAllBranch() {
return getJdbcTemplate().queryForList("SELECT * FROM jrnl.BRANCH", new Object[0]);
}
/**
* Clears the Entry table.
*/
protected void clearEntryTable() {
getJdbcTemplate().update("delete from jrnl.ENTRY", new Object[0]);
}
/**
* Will return the test User for use by sub classes.
*
* @return the test user.
*/
protected User getTestUser() {
return getJdbcTemplate().queryForObject(SQL_USER, new RowMapper<User>() {
@Override
public User mapRow(final ResultSet resultSet, final int rowNum) throws SQLException {
final User user = new User(resultSet.getString("USERNAME"));
user.setPassword(resultSet.getString("PASSWORD"));
user.setChecksum(resultSet.getString("checksum"));
user.setCreateDate(resultSet.getDate("create_date"));
user.setCreateTime(resultSet.getTime("create_time"));
user.setUpdateDate(resultSet.getDate("update_date"));
user.setUpdateTime(resultSet.getTime("update_time"));
return user;
}
}, new Object[] { JournalTestCommon.TEST_USERNAME });
}
/**
* Helper method to getRecord count of a table.
*
* @param tableName table name.
* @return count of records in the table.
*/
protected int getRecordCount(final String tableName) {
final String query = "SELECT count(*) FROM " + tableName;
return getJdbcTemplate().queryForInt(query);
}
/** @return the logger. */
public Log getLogger()
{
return logger;
}
/**
* @return the branchTableName
*/
public String getBranchTableName() {
return TBL_BRANCH;
}
/**
* @return the entryTableName
*/
public String getEntryTableName() {
return TBL_ENTRY;
}
/**
* @return the configTableName
*/
public String getConfigTableName() {
return TBL_CONFIG;
}
/** @return the jdbcTemplate. */
public SimpleJdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
/** @param pJdbcTemplate the jdbcTemplate to set. */
public void setJdbcTemplate(final SimpleJdbcTemplate pJdbcTemplate) {
this.jdbcTemplate = pJdbcTemplate;
}
protected JournalTestCommon getCommon() {
return common;
}
}