在做項目的時候,經常看見很多兄弟們在做一些無用功,其實,現在java語言已經形成了一個形形色色的生態圈,在這個生態圈里,有IT巨鱷的IBM,有兩頭受氣的Sun,還有各種各樣為我們提供工具的開源社區,如Apache,eclipse,freshmeat,sourceforge,netbeans等。此外,J2SE 5.0推出以后也為我們節省了不少工作。我們完全可以利用這些資源,節省很多為老板干活的時間,從而將有限的生命投入到無限的泡MM事業中去。
閑言少敘,dingdang預備寫個系列文章,講述一些工具,API以及其背后的原理。兄弟拋塊磚先,有玉的盡管砸過來,我閃
一,測試工具EasyMock
在這個系列文章中以測試開始,把它作為我們這篇入門介紹文檔的開頭,不是偶然的,正如村上春樹在《挪威的森林》里面說的那樣,死并不是生的對立面,而是作為生的一部分而存在。測試也不是開發的對立面,而是作為開發的一部分而存在,我們總是在不斷的寫代碼,單元測試,寫代碼,單元測試......作為單元測試的工具JUnit框架大家可能已經耳熟能詳,Martin Fowler對它的評價是"Never in the field of software development was so mUCh owed by so many to so few lines of code"。一時AUnit,BUnit,仿效者無數。可謂武林至尊
可是,僅僅JUnit是不夠的。我們在做項目的時候就碰到了這樣的場景:
大米:終于寫完代碼了,可以上QQ泡MM了.....
dingdang:哦,寫完了,給個測試用例先。
大米:沒法子給測試用例啊,我寫的這個類要用到苞谷寫的類耶
dingdang去找苞谷:苞谷,你的代碼怎么還沒寫完啊,搞的大米連單元測試都做不了。
苞谷:不是我得錯,蘋果沒有寫完我需要的類
蘋果:也不是我得錯,大米沒有寫完我需要的類
dingdang:×※……%¥
其實,這些類的依靠關系首先是違反了一個原則:The Dependency Inversion PRinciple(依靠轉置原則)
抽象不應該依靠于細節,而細節應該依靠于抽象。
高層的模塊不應該依靠于底層的模塊,它們都應該依靠于抽象
通俗一點的說,就是,我們在做Java設計的時候,應該盡可能的依靠于接口而不是實現。
dingdang嘿嘿奸笑兩聲:大米啊,我們修改一下設計吧,把我們的設計refactoring一下。
三分鐘后,大米說:dingdang啊,改成接口還是沒法子測試啊。
dingdang再次狂笑:哈哈,倚天不出,誰與爭鋒,看我的easymock!!!!!
easymock軟件安裝很簡單,先到以下地址下載一個最新的zip包: www.easymock.org,下載完以后將easymock.jar包加到你的系統的CLASSPATH環境變量中,對于IDE環境,對于需要用到的junit的項目增加到lib中,不同的IDE有不同的設置,這里不多講。
easymock的優點在于模擬接口的行為,(新版的easymock利用cglib據說也可以模擬類的行為,沒有試用過:P)假如你有一個類HelloWorld,依靠接口DependentInterface,easymock就可以在運行的時候生成DependentInterface接口的實現。這些實現的行為和返回值都可以在單元測試代碼里面指定。我們用一個JUnit例子來進行說明
首先,需要導入MockControl類,如下樣例中的第一步,
然后選擇一個接口,創建這個接口的模擬實例,如以下樣例中的第二步。
最后,先模擬一下你希望的類的行為,如返回值等,調用MockControl類的replay方法:
import junit.framework.*;
import org.easymock.MockControl;// step 1
interface DependentInterface{
public String sayHello();
}
class HelloWorld{
private DependentInterface dp_;
public HelloWorld(DependentInterface dp){
dp_ = dp;
}
public String sayAnotherHello(){
return dp_.sayHello();
}
}
public class TestHelloWorld extends TestCase {
private HelloWorld helloWorld_ = null;
private MockControl control_;
private DependentInterface dp_;
protected void setUp() throws Exception {
super.setUp();
control_ = MockControl.createControl(DependentInterface.class);//step 2
dp_ =(DependentInterface)control_.getMock();//step 2
helloWorld_ = new HelloWorld(dp_);
}
protected void tearDown() throws Exception {
helloWorld_ = null;
super.tearDown();
}
public void testSayHello() {
dp_.sayHello();//step 3
control_.setReturnValue("hello");//step 3
control_.replay();//step 3
String actualReturn = helloWorld_.sayAnotherHello();
assertEquals(actualReturn,"hello");
}
}
新聞熱點
疑難解答