亚洲好骚综合-亚洲黄色录像-亚洲黄色网址-亚洲黄色网址大全-99久久99久久-99久久99久久精品国产

您的位置:軟件測試 > 開源軟件測試 > 開源單元測試工具 >
追求代碼質量: 親身體驗行為驅動開發
作者:網絡轉載 發布時間:[ 2013/2/25 14:28:41 ] 推薦標簽:

杰出的 expectation 和 override

        在清單 3 中發生的一些事情是 JBhave 特有的,所以要解釋一下。首先,我創建 Stack 類的一個實例,并將它限制為 String 類型(通過 Java 5 泛型)。接下來,我使用 JBehave 的 異常框架 實際建模我所期望的行為。 Ensure 類類似于 JUnit 或 TestNG 的 Assert 類型;但是,它增加了一系列方法,提供了更具可讀性的 API(這常被稱作文學編程)。在清單 3 中,我確保了如果對 null 調用 push(),則拋出一個 RuntimeException。

        JBehave 還引入了一個 Block 類型,它是通過用所需的行為覆蓋 run() 方法來實現的。在內部,JBehave 確保期望的異常類型不被拋出(并因此被捕捉),而是生成一個故障狀態。您可能還記得,在我前面關于 用 Google Web Toolkit 對 Ajax 進行單元測試 的文章中,也出現了類似的覆蓋便利類的模式。在那種情況下,覆蓋是通過 GWT 的 Timer 類實現的。

        如果現在運行清單 3 中的行為,應該看到出現錯誤。按照目前編寫的代碼,push() 方法不執行任何操作。所以不可能生成異常,從清單 4 中的輸出可以看到這一點。


清單 4. 沒有發生期望的行為
              
1) StackBehavior should throw exception upon null push:
VerificationException: Expected:
object not null
but got:
null:
 


        清單 4 中的句子 “StackBehavior should throw exception upon null push” 模擬行為的名稱(shouldThrowExceptionUponNullPush()),并加上類的名稱。 實際上,JBehave 是在報告當它運行所需的行為時,沒有獲得任何反應。當然,我的下一步是要使上述行為成功運行,為此我檢查 null,如清單 5 所示。


清單 5. 在棧類中增加指定的行為
              
public void push(E value) {
  if(value == null){
   throw new RuntimeException("Can't push null");
  }
}
 


        當我重新運行行為時,一切都運行得很好,如清單 6 所示。


清單 6. 成功!
              
Time: 0.021s

Total: 1. Success!
 


行為驅動開發

        清單 6 中的輸出與 JUnit 的輸出是不是很像?這也許不是巧合,對不對?如前所述,JBehave 是根據 xUnit 范例建模的,它甚至通過 setUp() 和 tearDown() 提供了對 fixture 的支持。由于我可能在整個行為類中使用一個 Stack 實例,我可能也會將那種邏輯推入(這里并非有意使用雙關語)到一個 fixture 中,正如清單 7 中那樣。注意, JBehave 將與 JUnit 一樣遵循相同的 fixture 規則 — 也是說,對于每個行為方法,它都運行一個 setUp() 和 tearDown()。


清單 7. JBehave 中的 fixture
              
public class StackBehavior {
 private Stack<String> stStack;
 
 public void setUp() {
  this.stStack = new Stack<String>();
 }
 //...
}
 


        對于接下來的行為方法,shouldThrowExceptionUponPopWithoutPush() 表示我必須確保它具有類似于 清單 3 中的 shouldThrowExceptionUponNullPush() 的行為。從清單 8 中可以看出,沒有任何特別神奇的地方 — 有嗎?


清單 8. 確保 pop 的行為
              
public void shouldThrowExceptionUponPopWithoutPush() throws Exception{
 
 Ensure.throwsException(RuntimeException.class, new Block() {
   public void run() throws Exception {
    stStack.pop();
   }
 });
}
 


        您可能已經清楚地知道,此時清單 8 并不會真正地編譯,因為 pop() 還沒有被編寫。但是,在開始編寫 pop() 之前,讓我們考慮一些事情。

確保行為

        從技術上講,在這里我可以將 pop() 實現為無論調用順序如何,都只拋出一個異常。但是當我沿著這條行為路線前進時,我又忍不住考慮一個支持我所需要的規范的實現。在這種情況下,如果 push() 沒有被調用(或者從邏輯上講,棧為空)的情況下確保 pop() 拋出一個異常,則意味著棧有一個狀態。正如之前 Linda 思考的那樣,棧通常有一個 “內部容器”,用于實際持有項目。相應地,我可以為 Stack 類創建一個 ArrayList,用于保持傳遞給 push() 方法的值,如清單 9 所示。


        清單 9. 棧需要一種內部的方式來持有對象
              
public class Stack<E> {
 private ArrayList<E> list;

 public Stack() {
  this.list = new ArrayList<E>();
 }
 //...
}
 


        現在我可以為 pop() 方法編寫行為,即確保當棧在邏輯上為空時,拋出一個異常。


清單 10. pop 的實現變得更容易
              
public E pop() {
 if(this.list.size() > 0){
  return null;
 }else{
  throw new RuntimeException("nothing to pop");
 }
}
 


        當我運行清單 8 中的行為時,一切如預期運行:由于棧中沒有存在任何值(因此它的大小不大于 0),于是拋出一個異常。

        接下來的行為方法是 shouldPopPushedValue(),這個行為方法很容易指定。我只是 push() 一個值(“test”),并確保當調用 pop() 時,返回相同的值。

上一頁1234下一頁
軟件測試工具 | 聯系我們 | 投訴建議 | 誠聘英才 | 申請使用列表 | 網站地圖
滬ICP備07036474 2003-2017 版權所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd
主站蜘蛛池模板: 亚洲欧美成人 | 国产亚洲欧美ai在线看片 | 中文字幕一区二区三区 精品 | 亚洲一区二区三区四区在线 | 青青草成人免费 | 先锋悠悠xfplay色资源网站 | 亚洲精品一卡2卡3卡三卡四卡 | 夜夜澡人人爽人人喊_欧美 夜夜躁天天躁很很躁 | 日本精品视频一区二区 | 激情影院a | 亚洲黄色小视频 | 免费在线看污视频 | 成人小视频在线播放 | 亚洲国产福利精品一区二区 | 一区二区视频在线免费观看 | 免费色在线 | 色先锋资源网 | 色综合久久精品中文字幕 | 国产精品一区二区三区久久 | 亚洲天堂久久新 | 中国一级淫片bbb | 女人找男人皮日日视频 | 国产欧美激情一区二区三区-老狼 | 日本福利片在线观看 | 日韩经典中文字幕 | 最近的中文字幕视频完整 | 国产一区视频在线免费观看 | 春菜花在线中文字幕hd | 亚洲五月六月丁香激情 | 日本videos高清hd| 首页 国产 制服 丝袜 | 怡春院日本一区二区久久 | 老司机av磁力 | 亚洲国产成人久久 | 男女生性毛片免费观看 | 一级爱一级做a性视频 | 国产chaopeng视频在线 | 曰本三级黄色片 | 永久免费在线视频 | 成人欧美一区二区三区黑人 | 亚洲第一网站免费视频 |