應用設計模式編寫易于單元測試的代碼[8] 單元測試方法
替換實現
通過 Factory Method 替換被創建對象可以滿足一些修改程序運行路徑的需求,但是,這種方法以子類化為前提,具有很強的侵入性,并且在編寫單元測試時,開發人員需要同時負責 Mock Objects 的開發,供 Factory Method 調用,因此,編碼量往往會比較大,單元測試開發人員也需對所使用的公共模塊的內部結構有十分清楚的認識。即使可以使用公共的 Mock Objects 實現避免代碼重復,往往也需要修改業務邏輯中公共服務相關對象的創建代碼,這一點對于應用公共模塊的業務邏輯的單元測試可能不太適合。
在筆者曾參與設計、開發的某應用系統中,有一個專門的數據庫緩沖(Cache)公共服務,該 Cache 負責完成與數據庫交互,實現數據的存取,并緩存數據以提高后續訪問的效率。對于涉及數據庫緩沖的業務邏輯的單元測試,需要一個替代方案來替代已有的數據庫緩沖,以避免直接訪問實際數據庫,但又要保證這個替換不會影響到被測試單元的實現。
為了解決這個問題,我們并沒有直接替換 Cache 創建處的代碼,因為這些代碼遍布在業務代碼中,直接替換 Cache 創建代碼無疑會侵入業務邏輯,并需要大量使用子類化。為了盡可能降低對業務邏輯的影響,我們維持了原有 CacheFactory 的接口,但是將 CacheFactory 的實現委托(Delegate)給另一個實現類完成,以下是 CacheFactory 實現的偽代碼: 軟件測試
package com.cachefactory.demo;
public abstract class CacheFactory {
private static CacheFactoryinstance = new DelegateCacheFactory();
private static CacheFactorydelegate;
protected CacheFactory() {
}
// CacheFactory is a singletonpublic
static CacheFactory getInstance() {
return instance;
}
// the implementation can be changedprotected
static void setDelegate(CacheFactory instance) {
delegate= instance;
}
public abstract Cache getCache(Object... args);
// redirect all request to delegateeprivate
static class DelegateCacheFactoryextendsCacheFactory {
private DelegateCacheFactory() {
}
public Cache getCache(Object... args) {
return delegate.getCache(args);
}
}
}
文章來源于領測軟件測試網 http://www.k11sc111.com/