在財稅案的單元測試中使用DBUnit,來進行DAO的unit Test,
但是因為原本的寫法有點雜亂,所以來調整一下
在財稅案的單元測試中使用DBUnit,來進行DAO的unit Test,
但是因為原本的寫法有點雜亂,所以來調整一下
原本寫法
@DataSetLocation("classpath:/gov/fdc/tac/TACT005_dataset.xml")
public class TACT005DaoImplTest extends AbstractTACCoreTests {
Logger logger = LoggerFactory.getLogger(TACT005DaoImplTest.class);
TACT005Dao TACT005Dao;
@PersistenceContext
private EntityManager entityManager;
@Before
public void setUp() throws Exception {
TACT005Dao = new TACT005DaoImpl();
JPQLLoader jpqlLoader = new JPQLLoader();
jpqlLoader.setApplicationContext(applicationContext);
jpqlLoader.initJPQL();
//取得openJPA entity的連線設定
for (Field field : OpenJPADaoImpl.class.getDeclaredFields()) {
if (EntityManager.class.isAssignableFrom(field.getType())) {
field.setAccessible(true);
field.set(TACT005Dao, entityManager);
}
if (JPQLLoader.class.isAssignableFrom(field.getType())) {
field.setAccessible(true);
field.set(TACT005Dao, jpqlLoader);
}
}
}
@Test
public void testTACT005(){
TACT005 tact005 = TACT005Dao.query(new TACT005(), new TACT005PK());
assertNotNull(tact005);
}
可以看到setUp中有很多固定的寫法,這些是可以抽出來的...於是我就把他pull up了~
在父類別AbstractTACCoreTests去處理這些無聊的事情,就是說「想要嗎?爸爸買給你~」這樣。
public class AbstractTACCoreTests extends AbstractSDPUserAwareTests {
public Logger logger = LoggerFactory.getLogger(getClass());
private JPQLLoader jpqlLoader;
@PersistenceContext
private EntityManager entityManager;
private AsYouWishEntityManagerSelector emSelector;
/**初始化單元測試類別,進行物件的實作及注入相關類別
* @param targetObj
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IOException
*/
public void init(Object targetObj) throws IllegalArgumentException, IllegalAccessException, SecurityException,
NoSuchFieldException, IOException {
List injectDaoList = new ArrayList();
Object managerImpl = null;
for (Field f : targetObj.getClass().getDeclaredFields()) {
if (f.isAnnotationPresent(InjectTACTest.class)
&& (f.getType().getName().indexOf("Dao") >= 0 || f.getType().getName().indexOf("Manager") >= 0)) {
String implObjNm = f.getType().getName();
logger.info("符合條件的FIELD:" + implObjNm);
// 取得實作類別的完整名稱
implObjNm = getImplObjName(implObjNm);
try {
Object implObjInstance = Class.forName(implObjNm).newInstance();
logger.info(implObjNm + "建立成功!");
boolean isAccessable = f.isAccessible();
if (!(isAccessable)) {
f.setAccessible(true);
}
//設定實作類別給單元測試物件
managerImpl = setField(targetObj, injectDaoList, f, implObjInstance);
logger.info(implObjNm + "assign成功!");
} catch (Exception e) {
logger.error(implObjNm + "建立失敗!");
e.printStackTrace();
}
}
}
//將dao必要欄位 注入 jpqlLoader及 EntityManager
initDao(injectDaoList);
if (null != managerImpl) {
//將dao注入到manager中
initManager(managerImpl, injectDaoList);
}
}
/**
* 將dao必要欄位 注入 jpqlLoader及 EntityManager
*
* @param injectDaoList
* injectDaoList
* @throws IllegalArgumentException
* IllegalArgumentException
* @throws IllegalAccessException
* IllegalAccessException
* @throws NoSuchFieldException
* @throws SecurityException
* @throws IOException
*/
public void initDao(List injectDaoList) throws IllegalArgumentException, IllegalAccessException, SecurityException,
NoSuchFieldException, IOException {
if (jpqlLoader == null) {
jpqlLoader = new JPQLLoader();
jpqlLoader.setApplicationContext(applicationContext);
jpqlLoader.initJPQL();
}
if (null == emSelector) {
emSelector = new AsYouWishEntityManagerSelector(entityManager);
}
for (Object dao : injectDaoList) {
ObjectRobber.set(dao, "entityManagerSelector", emSelector);
ObjectRobber.set(dao, "jpqlLoader", jpqlLoader);
logger.info(dao.getClass().getName() + "注入成功!");
}
}
/**
* 將dao注入到manager中
*
* @param managerImpl
* managerImpl
* @param injectDaoList
* injectDaoList
* @throws SecurityException
* SecurityException
* @throws IllegalAccessException
* IllegalAccessException
*/
public void initManager(Object managerImpl, List injectDaoList) throws SecurityException,
IllegalAccessException {
for (Dao dao : injectDaoList) {
// Dao取得entity連線後注入APPBasicSampleManagerImpl
ObjectRobber.manualWire(managerImpl, dao);
}
}
/**設定實作類別給單元測試物件
* @param targetObj
* @param injectDaoList
* @param feild
* @param implObjInstance
* @return
* @throws IllegalAccessException
*/
private Object setField(Object targetObj, List injectDaoList, Field feild, Object implObjInstance)
throws IllegalAccessException {
String implObjNm = feild.getType().getName();
Object managerImpl = null;
feild.set(targetObj, implObjInstance);
if (implObjNm.indexOf("DaoImpl") == -1) {
injectDaoList.add(implObjInstance);
}else if (implObjNm.indexOf("ManagerImpl") == -1) {
managerImpl = implObjInstance;
}
return managerImpl;
}
/**取得實作類別的完整名稱
* @param objNm
* @return implObjNm
*/
private String getImplObjName(String objNm) {
String implObjNm = objNm;
if (objNm.indexOf("DaoImpl") == -1) {
int idx = objNm.lastIndexOf(".");
implObjNm = objNm.substring(0, idx) + ".impl" + objNm.substring(idx, objNm.length()) + "Impl";
}else if (objNm.indexOf("ManagerImpl") == -1) {
int idx = objNm.lastIndexOf(".");
implObjNm = objNm.substring(0, idx) + ".impl" + objNm.substring(idx, objNm.length()) + "Impl";
}
return implObjNm;
}
同時還寫了一個annotaion作為標記使用。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectTACTest {}
這樣子整理過後的單元測試程式就乾淨多了。
易容後效果如下:
@DataSetLocation("classpath:/gov/fdc/tac/TACT005_dataset.xml")
public class TACT005DaoImplTest extends AbstractTACCoreTests {
Logger logger = LoggerFactory.getLogger(TACT005DaoImplTest.class);
@InjectTACTest
TACT005Dao TACT005Dao;
@Before
public void setUp() throws Exception {
init(this);
}
@Test
public void testTACT005(){
TACT005 tact005 = TACT005Dao.query(new TACT005(), new TACT005PK());
assertNotNull(tact005);
}
這樣是不是爽多了~~
沒有留言:
張貼留言