在RCP程序中进行单元测试

最近刚刚接触RCP这个东西,其中如何进行单元测试让我头疼了好几天。
搜索了一下,倒是发现了许多测试工具,但是,要么是收钱的,要么是安装不方便,要么是
使用麻烦。

总之,没找到好用的。

最后,无奈之下,决定使用最古老的方式-----MOCK!这绝对不是一个好的方式,但是,如果你想

自如的进行单元测试,倒是一个可以考虑的方式。

RCP程序不同于WEB程序,RCP的程序就是普通的JAVA类,运行的时候也不需要额外的服务器。

那么,我们能不能象运行一个普通的JAVA类那样来运行一个RCP程序呢?
答案是否定的,因为RCP运行的时候需要RCP的环境。

那么我们就来MOCK!

例如我有一个 Editor 类,

java 代码
  1. public class NewOrderEditor extends EditorPart {   
  2.   
  3.     private Text text_1;   
  4.   
  5.     public void createPartControl(Composite parent) {   
  6.   
  7.            .....   
  8.            .....   
  9.     }   
  10.   
  11.   
  12. }  

首先,我把这个类拷贝到测试目录里,然后改个名字,例如叫 NewOrderEditorMock.java。

然后,开始Mock,原则就是脱离一切 swt 等组件!

所有的 Text, Button, Table, TableItem, CheckBoxTableViewer 全部都自己写一个模拟类,
其中所需要的方法也实现一个模拟的。

例如这就是一个模拟类:

java 代码
  1. public class CheckboxTableViewer {   
  2.        
  3.     private Table table = new Table();   
  4.        
  5.     public static CheckboxTableViewer newCheckList(Composite parent, int style) {   
  6.            
  7.         return new CheckboxTableViewer();   
  8.     }   
  9.        
  10.     public Table getTable() {   
  11.            
  12.         return table;   
  13.     }   
  14.   
  15.     public Object[] getCheckedElements() {   
  16.         // TODO Auto-generated method stub   
  17.            
  18.         java.util.List<TableItem> itemList = table.getTableItemList();   
  19.         java.util.List elementList = new ArrayList();   
  20.            
  21.         for(TableItem item : itemList ) {   
  22.                
  23.             if(item.isCheck()) {   
  24.                 elementList.add(item.getData());   
  25.             }   
  26.         }   
  27.            
  28.   
  29.         if(elementList.size()==0) {   
  30.             return null;   
  31.         }   
  32.            
  33.            
  34.         return elementList.toArray(new Object[elementList.size()]);   
  35.     }   
  36.        
  37.     public void selectLine(int line) {   
  38.            
  39.         TableItem tableItem = table.getTableItemList().get(line);   
  40.         tableItem.setCheck(true);   
  41.     }   
  42.        
  43.        
  44.        
  45. }  

 

java 代码
  1. public class Table {   
  2.        
  3.     List<TableColumn> tableColumnList = new ArrayList<TableColumn>();   
  4.     List<TableItem> tableItemList = new ArrayList<TableItem>();   
  5.        
  6.     public void setLinesVisible(boolean b) {   
  7.            
  8.     }   
  9.        
  10.     public void setHeaderVisible(boolean b) {   
  11.            
  12.     }   
  13.   
  14.     public void setBackground(Color color) {   
  15.         // TODO Auto-generated method stub   
  16.            
  17.     }   
  18.   
  19.     public void setLayoutData(GridData gd_tle_resultset) {   
  20.         // TODO Auto-generated method stub   
  21.            
  22.     }   
  23.   
  24.     public void removeAll() {   
  25.         // TODO Auto-generated method stub   
  26.         tableColumnList.clear();   
  27.         tableItemList.clear();   
  28.            
  29.     }   
  30.   
  31.     public TableItem getItem(int selectIndex) {   
  32.         // TODO Auto-generated method stub   
  33.         return tableItemList.get(selectIndex);   
  34.     }   
  35.   
  36.     public void remove(int[] index) {   
  37.         // TODO Auto-generated method stub   
  38.         for(int i = 0; i< tableItemList.size(); i++) {   
  39.                
  40.             for(int j = 0; j < index.length; j++) {   
  41.                 if(i==index[j]) {   
  42.                     tableItemList.remove(i);   
  43.                     i--;   
  44.                     break;   
  45.                 }   
  46.             }   
  47.         }   
  48.            
  49.     }   
  50.   
  51.     public int getItemCount() {   
  52.         // TODO Auto-generated method stub   
  53.         return tableItemList.size();   
  54.     }   
  55.   
  56.     public TableItem[] getItems() {   
  57.         // TODO Auto-generated method stub   
  58.         return tableItemList.toArray(new TableItem[tableItemList.size()]);   
  59.     }   
  60.   
  61.     public int getColumnCount() {   
  62.         // TODO Auto-generated method stub   
  63.         return tableColumnList.size();   
  64.     }   
  65.   
  66.     public TableColumn getColumn(int n) {   
  67.         // TODO Auto-generated method stub   
  68.         return tableColumnList.get(n);   
  69.     }   
  70.   
  71.     public List<TableColumn> getTableColumnList() {   
  72.         return tableColumnList;   
  73.     }   
  74.   
  75.     public void setTableColumnList(List<TableColumn> tableColumnList) {   
  76.         this.tableColumnList = tableColumnList;   
  77.     }   
  78.   
  79.     public List<TableItem> getTableItemList() {   
  80.         return tableItemList;   
  81.     }   
  82.   
  83.     public void setTableItemList(List<TableItem> tableItemList) {   
  84.         this.tableItemList = tableItemList;   
  85.     }   
  86.   
  87.   
  88.        
  89. }  

这么做确实很麻烦,不过好在很多方法都很容易模拟 ----- 这不是你的水平高,而是因为那些
组件使用了MVC模式,写模拟方法的时候,根本无须考虑视图的问题。

至于鼠标点击按钮,就更容易了-----因为那好比直接调用类里的一个方法!

编写模拟的过程并不容易,因为有的时候,你会发现你要模拟更多的类----在这个过程中,我
怀疑我做的到底有没有意义?不过我还是做了,因为只有做过了,才能知道。

终于,模拟类都写完了,我开始测试一个 editor 界面。

测试类真的是太好写了,我可以和程序中的任何一个类进行交互,因为目前这个模拟的界面
就是一个普通的类。
这其中我测试出了一些BUG,进行了修改。也测试出了一些模拟类的问题,当然也对其进行了
修改。

当全部的测试通过以后,我再使用eclipse的比较功能,把模拟的界面类和真正的界面类进行了
代码合并。

之后 .... .....

我还有下一个界面要进行编码,在编码之前,我重复之前的步骤,复制了一个模拟类,把 swt
等相关的东西删除了,导入模拟的类。这次我没那么麻烦,因为很多东西在上一个过程里都创建
好了。

直到这里,我仍然不知道我所做的是否有意义,因为这么做很麻烦---我每次都需要合并模拟类
和真正的类的代码。Eclipse的代码比较功能非常强大,但手动合并还是麻烦。

但是,所得到的回报就是测试非常方便,非常方便!

在我没有发现一个非常棒的工具之前,我还是暂时使用这种方式,直到项目的结束。
或许在结束之前,我就会因为模拟类的繁多而停止使用这种方式,
也或许直到结束,我都会一直使用这种方式,而且发现它会越来越好用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值