為什么把Spring MVC引入到接口測試中
在閱讀xx系統(tǒng)的源代碼進行接口測試的過程中,發(fā)現不止此系統(tǒng),主流運用的都是Spring MVC + Mybatis的框架來開發(fā)web。
發(fā)現這是個很有趣的事物,學習了一段時間,認為里面的一些個編程思想可以引入到接口測試中來。比如spring的AOP(面向切面的編程),DI也就是依賴注入或者控制反轉。
聽起來很高大上的詞匯,經過一番實踐,發(fā)現能夠有所理解并且也引入到了接口測試中來。
先以我工程的代碼片段來舉例說明,什么叫Spring的依賴注入。
這里有三張圖,第一張是使用NodeService,從第三張圖中我們可以看到NodeSerice其實就只是一個接口,那么為什么在我的接口測試代碼中可以直接調用它的方法呢:
從第二張圖中,是這個接口的實現方法。打了一個@Service的注解。這個@Service的注解就是要告訴Spring框架,這是一個JAVA Bean。
那么,神奇的事情發(fā)生了。Spring在我的測試業(yè)務代碼中,使用如下的注解@Autowired,這樣Spring就把NodeServiceImpl的實例給創(chuàng)建出來了。
這就是所謂的依賴注入,或者是控制反轉。因為實例化NodeServiceImpl的操作Spring幫我們做了,所謂的控制權從我們的業(yè)務測試代碼轉移給了Spring。
那么,這其實就是我理解的AOP,所謂的面向配置或面向切面的編程。在你的業(yè)務代碼里切入一刀,然后把實例注入進去。,這里說說一句話的事兒,說實話這一句話讓我理解了好久。
(其實@Resource也可以,他們有區(qū)別,但是我沒搞清楚具體使用起來的區(qū)別)
往常的做法應該是如下面的示例,需要new一個實例。
更近一層,既然知道了這樣的編程思想。為啥不能把我們常用的HTTP請求的類給轉化成這樣的呢。答案是肯定的,當然可以。如下面幾幅圖:
就這樣,我們HTTP也是提供給業(yè)務測試的一種Service。
為什么把Mybatis引入到接口測試中
Mybatis是一款輕量級的持久層框架,也是此系統(tǒng)進行Dao訪問用到的框架。我不知道Hibernate,不要問我區(qū)別在哪里,輕在哪里,我只知道很輕便。
依舊舉例說明:
首先,展示一下DB層的JAVA代碼映射,如下面2張圖:
Node是xx系統(tǒng)的一張表,格式如下:
可以看出來Node這個class的所有屬性,就是對節(jié)點表Node的映射。這就是所謂的DB層。
那么Dao層怎么實現的呢,先看圖:
只要定義一個NodeMapper的Interface,然后配置一個nodeMapper.xml,然后我們看到Mapper文件引用的就是NodeMapper這個接口,然后下面的id = create, retrieveById,retrieveByName。很明顯,就是這些Interface方法的實現。然后具體內容其實就是帶有變量的SQL語句。
簡單的講,其實Mybatis就是這樣容易。不用你在使用JDBC的方式把SQL語句以String的方式寫入到代碼中。只需要的一個配置文件。這也是所謂的面向切面/配置的編程。
如何搭建環(huán)境實現
如何使上面這些體系運行起來,這里其實就是Spring的配置的問題。
第一部分:將Spring把所有的JAVA Bean掃進來
第二部分:指定數據源dataSource,也就是MySql連接池
第三部分:將Mybatis和Spring整合
SqlSessionFactoryBean這個類是Spring提供應用于建立SQL連接池的。
其中:
- typeAliasesPackage:它一般對應我們的實體類所在的包,這個時候會自動取對應包中不包括包名的簡單類名作為包括包名的別名。多個package之間可以用逗號或者分號等來進行分隔。
- MapperScannerConfigurer:
利用上面的方法進行整合的時候,我們有一個Mapper就需要定義一個對應的MapperFactoryBean,當我們的Mapper比較少的時候,這樣做也還可以,但是當我們的Mapper相當多時我們再這樣定義一個個Mapper對應的MapperFactoryBean就顯得速度比較慢了。為此Mybatis-Spring為我們提供了一個叫做MapperScannerConfigurer的類,通過這個類Mybatis-Spring會自動為我們注冊Mapper對應的MapperFactoryBean對象。
好了。你可以做TestNG的測試業(yè)務代碼編寫了。
如何進行TestNG和Spring的結合
在每一個測試類中按照下面這么配置:
@ContextConfiguration和AbstractTestNGSpringContextTests就可以做到。
原因是:因為我這個是Maven工程,執(zhí)行的是Maven test命令。而Spring運行test的時候是一個隔離的狀態(tài)。所以沒有辦法注入。
這里找到的答案:
“If you create unit tests, Spring IoC functionality is unavailable(as it was intended by the framework designers), because you are testing your objects in isolation(i.e. you are mocking only minimal set of interfaces which are required for the test to complete). “
繼續(xù)你的業(yè)務代碼編寫吧。
其他
IDE的選擇
IntelliJ IDEA真的是太好用了。
- 天生集成了Maven, Git。并且比如什么markdown語言啊,freeMarker,git的ignore文件這些都是可以智能編寫。
- 有code inspection功能。你Git push的時候它會有個選項讓你做一下code inspection再說..
- 而且正如名字所說,智能。聯想功能很強大。
- 長得好看,速度快..
技巧
- Alt+F8,呼喚出Maven的window。
- shift+esc,退出窗口
- Ctrl+alt+S, 呼喚出Setting配置出現錯誤的時候,
- alt+Enter,出現錯誤時,它可以給很好聯想出解決辦法的。
- 可以選擇Eclipse的喜好,默認支持Eclipse的所有快捷鍵。
- 支持VIM編輯器,對于那些linux大神們,可以用這種全宇宙最強大的編輯器了。我不會用。
- ....
如何在TestNG中調試
配置maven命令如下
surefire是maven的一個插件,專門用來test的,TestNG的測試一系列比如報告生成啊,什么都是它來做的
建立一個Remote
這個5005端口是默認打開的一個用于連接的端口,在下面的圖會有體現。
運行Maven命令
這個時候test的進程就停在那里了。
運行Remote
這個時候,只要有斷點,就可以斷下來了。
至于TestNG本身的知識,這里就不多說了,很多注解和屬性我也在使用中。
碰見的坑
- Spring和TestNG的結合,請參閱前面的章節(jié),如果不這么做,TestNG是不會引入spring的所有配置文件的。
- TestNG的調試,參閱前面的章節(jié)
- StringEntity() 和 UrlEncodedFormEntity() 的區(qū)別:
加載HTTP參數的時候,之前用的UrlEncodedFormEntity,參數傳過去不識別。最后發(fā)現問題在這里。
httppost.setEntity(new StringEntity(JSON.toJSONString(params), "UTF-8"));
可以參考:鏈接
有啥問題,可以一起討論學習。